標籤:其他 ++ util comm 一個隊列 時間 none gif i++
摘自馬士兵java並發編程
一、認識Executor、ExecutorService、Callable、Executors
/** * 認識Executor */package yxxy.c_026;import java.util.concurrent.Executor;public class T01_MyExecutor implements Executor { public static void main(String[] args) { new T01_MyExecutor().execute(new Runnable(){ @Override public void run() { System.out.println("hello executor"); } }); } @Override public void execute(Runnable command) { //new Thread(command).run(); command.run(); }}
View Code Executor執行器是一個介面,只有一個方法execute執行任務,在java的線程池的架構裡邊,這個是最頂層的介面;ExecutorService:從Executor介面繼承。Callable:裡面call方法,和Runnable介面很像,設計出來都是被其他線程調用的;但是Runnable介面裡面run方法是沒有傳回值的也不能拋出異常;而call方法有傳回值可以拋異常;Executors: 操作Executor的一個工具類;以及操作ExecutorService,ThreadFactory,Callable等; 二、ThreadPool:
/** * 線程池的概念 */package yxxy.c_026;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.TimeUnit;public class T05_ThreadPool { public static void main(String[] args) throws InterruptedException { ExecutorService service = Executors.newFixedThreadPool(5); //execute submit for (int i = 0; i < 6; i++) { service.execute(() -> { try { TimeUnit.MILLISECONDS.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()); }); } System.out.println(service); service.shutdown(); System.out.println(service.isTerminated()); System.out.println(service.isShutdown()); System.out.println(service); TimeUnit.SECONDS.sleep(5); System.out.println(service.isTerminated()); System.out.println(service.isShutdown()); System.out.println(service); }}
View Code
console:
[email protected][Running, pool size = 5, active threads = 5, queued tasks = 1, completed tasks = 0]falsetrue[email protected][Shutting down, pool size = 5, active threads = 5, queued tasks = 1, completed tasks = 0]pool-1-thread-1pool-1-thread-3pool-1-thread-2pool-1-thread-5pool-1-thread-4pool-1-thread-1truetrue[email protected][Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 6]
View Code建立了一個線程池,扔了5個線程,接下來要執行6個任務,扔進去線程池裡面就啟一個線程幫你執行一個,因為這裡最多就起5個線程,接下來扔第6個任務的時候,不好意思,它排隊了,排線上程池所維護的一個任務隊列裡面,任務隊列大多數使用的都是BlockingQueue,這是線程池的概念;有什麼好處?好處在於如果這個任務執行完了,這個線程不會消失,它執行完任務空閑下來了,如果有新的任務來的時候,直接交給這個線程來運行就行了,不需要新啟動線程;從這個概念上講,如果你的任務和線程池線程數量控制的比較好的情況下,你不需要啟動新的線程就能執行很多很多的任務,效率會比較高,並發性好; service.shutdown():關閉線程池,shutdown是正常的關閉,它會等所有的任務都執行完才會關閉掉;還有一個是shutdownNow,二話不說直接就給關了,不管線程有沒有執行完;service.isTerminated(): 代表的是這裡所有執行的任務是不是都執行完了。isShutdown()為true,注意它關了但並不代表它執行完了,只是代表正在關閉的過程之中(注意列印Shutting down)列印5個線程名字,而且第一個線程執行完了之後,第6個任務來了,第1個線程繼續執行,不會有線程6; 當所有線程全部執行完畢之後,線程池的狀態為Terminated,表示正常結束,complete tasks=6 線程池裡面維護了很多線程,等著你往裡扔任務,而扔任務的時候它可以維護著一個工作清單,還沒有被執行的工作清單,同樣的它還維護著另外一個隊列,complete tasks,結束的任務隊列,任務執行結束扔到這個隊列裡,所以,一個線程池維護著兩個隊列; 三、Future
/** * 認識future */package yxxy.c_026;import java.util.concurrent.ExecutionException;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Future;import java.util.concurrent.FutureTask;import java.util.concurrent.TimeUnit;public class T06_Future { public static void main(String[] args) throws InterruptedException, ExecutionException { /*FutureTask<Integer> task = new FutureTask<Integer>(new Callable<Integer>(){ @Override public Integer call() throws Exception { TimeUnit.MILLISECONDS.sleep(3000); return 1000; } });*/ FutureTask<Integer> task = new FutureTask<>(()->{ TimeUnit.MILLISECONDS.sleep(3000); return 1000; }); new Thread(task).start(); System.out.println(task.get()); //阻塞 //******************************* ExecutorService service = Executors.newFixedThreadPool(5); Future<Integer> f = service.submit(()->{ TimeUnit.MILLISECONDS.sleep(5000); return 1; }); System.out.println(f.isDone()); System.out.println(f.get()); System.out.println(f.isDone()); }}
View Code
1000false1true
View CodeFuture: ExecutorService裡面有submit方法,它的傳回值是Future類型,因為你扔一個任務進去需要執行一段時間,未來的某一個時間點上,任務執行完了產生給你一個結果,這個Future代表的就是那個Callable的傳回值; ---------------
java高並發編程(五)線程池