線程池基礎一
我們來看下面程序的代碼:經典的生產者消費者來實現
package com.bjsxt.height.design016; public final class Data { private String id; private String name; public Data(String id, String name){ this.id = id; this.name = name; } public String getId() { return id; }public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString(){ return "{id: " + id + ", name: " + name + "}"; } }
package com.bjsxt.height.design016; import java.util.Random; import java.util.concurrent.BlockingQueue; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; public class Provider implements Runnable{ //共享緩存區 private BlockingQueue<Data> queue;//多線程間是否啟動變量,有強制從主內存中刷新的功能。即時返回線程的狀態 private volatile boolean isRunning = true; //id生成器 private static AtomicInteger count = new AtomicInteger(); //隨機對象 private static Random r = new Random(); public Provider(BlockingQueue queue){ this.queue = queue; } @Override public void run() { while(isRunning){ try { //隨機休眠0 - 1000 毫秒 表示獲取數據(產生數據的耗時) Thread.sleep(r.nextInt(1000)); //獲取的數據進行累計... int id = count.incrementAndGet(); //比如通過一個getData方法獲取了 Data data = new Data(Integer.toString(id), "數據" + id); System.out.println("當前線程:" + Thread.currentThread().getName() + ", 獲取了數據,id為:" + id + ", 進行裝載到公共緩沖區中..."); if(!this.queue.offer(data, 2, TimeUnit.SECONDS)){ System.out.println("提交緩沖區數據失敗...."); //do something... 比如重新提交 } } catch (InterruptedException e) { e.printStackTrace(); } } } public void stop(){ this.isRunning = false; } }
package com.bjsxt.height.design016; import java.util.Random; import java.util.concurrent.BlockingQueue; import java.util.concurrent.TimeUnit; public class Consumer implements Runnable{ private BlockingQueue<Data> queue; public Consumer(BlockingQueue queue){ this.queue = queue; } //隨機對象 private static Random r = new Random(); @Override public void run() { while(true){ try { //獲取數據 Data data = this.queue.take(); //進行數據處理。休眠0 - 1000毫秒模擬耗時 Thread.sleep(r.nextInt(1000)); System.out.println("當前消費線程:" + Thread.currentThread().getName() + ", 消費成功,消費數據為id: " + data.getId()); } catch (InterruptedException e) { e.printStackTrace(); } } } }
package com.bjsxt.height.design016; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingQueue; public class Main { public static void main(String[] args) throws Exception { //內存緩沖區 BlockingQueue<Data> queue = new LinkedBlockingQueue<Data>(10); //生產者 Provider p1 = new Provider(queue); Provider p2 = new Provider(queue); Provider p3 = new Provider(queue); //消費者 Consumer c1 = new Consumer(queue); Consumer c2 = new Consumer(queue); Consumer c3 = new Consumer(queue); //創建線程池運行,這是一個緩存的線程池,可以創建無窮大的線程,沒有任務的時候不創建線程。空閑線程存活時間為60s(默認值) ExecutorService cachePool = Executors.newCachedThreadPool(); cachePool.execute(p1); cachePool.execute(p2); cachePool.execute(p3); cachePool.execute(c1); cachePool.execute(c2); cachePool.execute(c3); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } p1.stop(); p2.stop(); p3.stop(); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } // cachePool.shutdown(); // cachePool.shutdownNow(); } }
程序的運行結果是:
當前線程:pool-1-thread-2, 獲取了數據,id為:1, 進行裝載到公共緩沖區中...
當前線程:pool-1-thread-1, 獲取了數據,id為:2, 進行裝載到公共緩沖區中...
當前線程:pool-1-thread-3, 獲取了數據,id為:3, 進行裝載到公共緩沖區中...
當前線程:pool-1-thread-2, 獲取了數據,id為:4, 進行裝載到公共緩沖區中...
當前消費線程:pool-1-thread-6, 消費成功,消費數據為id: 3
當前消費線程:pool-1-thread-4, 消費成功,消費數據為id: 1
當前線程:pool-1-thread-3, 獲取了數據,id為:5, 進行裝載到公共緩沖區中...
當前線程:pool-1-thread-3, 獲取了數據,id為:6, 進行裝載到公共緩沖區中...
當前線程:pool-1-thread-1, 獲取了數據,id為:7, 進行裝載到公共緩沖區中...
當前消費線程:pool-1-thread-4, 消費成功,消費數據為id: 5
當前消費線程:pool-1-thread-5, 消費成功,消費數據為id: 2
當前線程:pool-1-thread-2, 獲取了數據,id為:8, 進行裝載到公共緩沖區中...
當前消費線程:pool-1-thread-6, 消費成功,消費數據為id: 4
當前線程:pool-1-thread-3, 獲取了數據,id為:9, 進行裝載到公共緩沖區中...
當前消費線程:pool-1-thread-5, 消費成功,消費數據為id: 7
當前線程:pool-1-thread-3, 獲取了數據,id為:10, 進行裝載到公共緩沖區中...
當前消費線程:pool-1-thread-6, 消費成功,消費數據為id: 8
當前線程:pool-1-thread-1, 獲取了數據,id為:11, 進行裝載到公共緩沖區中...
當前線程:pool-1-thread-1, 獲取了數據,id為:12, 進行裝載到公共緩沖區中...
當前線程:pool-1-thread-2, 獲取了數據,id為:13, 進行裝載到公共緩沖區中...
當前消費線程:pool-1-thread-4, 消費成功,消費數據為id: 6
當前線程:pool-1-thread-3, 獲取了數據,id為:14, 進行裝載到公共緩沖區中...
當前消費線程:pool-1-thread-5, 消費成功,消費數據為id: 9
當前線程:pool-1-thread-2, 獲取了數據,id為:15, 進行裝載到公共緩沖區中...
當前線程:pool-1-thread-1, 獲取了數據,id為:16, 進行裝載到公共緩沖區中...
當前消費線程:pool-1-thread-5, 消費成功,消費數據為id: 12
當前線程:pool-1-thread-3, 獲取了數據,id為:17, 進行裝載到公共緩沖區中...
當前消費線程:pool-1-thread-6, 消費成功,消費數據為id: 10
當前線程:pool-1-thread-2, 獲取了數據,id為:18, 進行裝載到公共緩沖區中...
當前消費線程:pool-1-thread-4, 消費成功,消費數據為id: 11
當前線程:pool-1-thread-1, 獲取了數據,id為:19, 進行裝載到公共緩沖區中...
當前消費線程:pool-1-thread-5, 消費成功,消費數據為id: 13
當前消費線程:pool-1-thread-5, 消費成功,消費數據為id: 16
當前消費線程:pool-1-thread-4, 消費成功,消費數據為id: 15
當前線程:pool-1-thread-3, 獲取了數據,id為:20, 進行裝載到公共緩沖區中...
當前消費線程:pool-1-thread-5, 消費成功,消費數據為id: 17
當前消費線程:pool-1-thread-6, 消費成功,消費數據為id: 14
當前消費線程:pool-1-thread-4, 消費成功,消費數據為id: 18
當前消費線程:pool-1-thread-5, 消費成功,消費數據為id: 19
當前消費線程:pool-1-thread-6, 消費成功,消費數據為id: 20
相當的經典
線程池基礎一