java高並發編程(五)線程池
阿新 • • 發佈:2018-08-28
pen style shutdown return turn lock close print dfa
摘自馬士兵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(){ @OverrideView Code Executor執行器是一個接口,只有一個方法execute執行任務,在java的線程池的框架裏邊,這個是最頂層的接口; ExecutorService:從Executor接口繼承。 Callable:裏面call方法,和Runnable接口很像,設計出來都是被其他線程調用的;但是Runnable接口裏面run方法是沒有返回值的也不能拋出異常;而call方法有返回值可以拋異常; Executors: 操作Executor的一個工具類;以及操作ExecutorService,ThreadFactory,Callable等; 二、ThreadPool:public void run() { System.out.println("hello executor"); } }); } @Override public void execute(Runnable command) { //new Thread(command).run(); command.run(); } }
/** * 線程池的概念 */ 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); //View Codeexecute 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); } }
console:
java.util.concurrent.ThreadPoolExecutor@53d8d10a[Running, pool size = 5, active threads = 5, queued tasks = 1, completed tasks = 0] false true java.util.concurrent.ThreadPoolExecutor@53d8d10a[Shutting down, pool size = 5, active threads = 5, queued tasks = 1, completed tasks = 0] pool-1-thread-1 pool-1-thread-3 pool-1-thread-2 pool-1-thread-5 pool-1-thread-4 pool-1-thread-1 true true java.util.concurrent.ThreadPoolExecutor@53d8d10a[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
1000 false 1 trueView Code Future: ExecutorService裏面有submit方法,它的返回值是Future類型,因為你扔一個任務進去需要執行一段時間,未來的某一個時間點上,任務執行完了產生給你一個結果,這個Future代表的就是那個Callable的返回值; ---------------
java高並發編程(五)線程池