摘要:實現初始化線程池數量策略并執行線程。二簡述下從定義線程池,到其底層執行的簡單流程簡單定義了如上兩句代碼,自動創建個固定大小的線程的線程池,實現了接口的對象以后,自動啟動線程并執行對象的方法。關鍵的調用類方法,管理線程池并執行任務。
一.類圖說明
Executor接口類,執行Runnable接口execute。
ExecutorService接口類繼承Executor接口,包含提交執行Runnable和Callable接口submit以及shutdown,invokeAll接口。
ScheduledExecutorService接口類繼承ExecutorService接口,主要包含計劃執行接口schedule,scheduleAtFixedRate以及scheduleWithFixedDelay。
虛類AbstractExecutorService,實現ExecutorService接口。實現ExecutorService相關接口。
ThreadPoolExecutor類,繼承虛類AbstractExecutorService。實現初始化線程池數量、策略并執行線程。
ScheduledThreadPoolExecutor類,繼承ThreadPoolExecutor類并實現ScheduledExecutorService接口。實現計劃執行相關接口。
執行類,定義ThreadPoolExecutor和ScheduledThreadPoolExecutor類,并使用相關concurrent類方法。
二.簡述下從定義線程池,到其底層執行的簡單流程
ExecutorService executorService = Executors.newFixedThreadPool(3); executorService.submit(new NewTask());
簡單定義了如上兩句代碼,JDK自動創建3個固定大小的線程的線程池,submit實現了Runnable接口的NewTask對象以后,JDK自動啟動線程并執行NewTask對象的run方法。流程是如何的呢?
1.Executors的newFixedThreadPool方法new了一個ThreadPoolExecutor對象,且new了一個LinkedBlockingQueue對象。
public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue()); }
2.調用ThreadPoolExecutor的構造函數,其中ThreadFactory默認使用defaultThreadFactory,defaultHandler為AbortPolicy。
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueueworkQueue) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), defaultHandler); } public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) { if (corePoolSize < 0 || maximumPoolSize <= 0 || maximumPoolSize < corePoolSize || keepAliveTime < 0) throw new IllegalArgumentException(); if (workQueue == null || threadFactory == null || handler == null) throw new NullPointerException(); this.corePoolSize = corePoolSize; this.maximumPoolSize = maximumPoolSize; this.workQueue = workQueue; this.keepAliveTime = unit.toNanos(keepAliveTime); this.threadFactory = threadFactory; this.handler = handler; }
3.初始化以后,調用AbstractExecutorService類的submit方法,執行Runnable對象。
public Future> submit(Runnable task) { if (task == null) throw new NullPointerException(); RunnableFutureftask = newTaskFor(task, null); execute(ftask); return ftask; }
4.RunnableAdapter實現了Callable接口,FutureTask類包含callable類成員對象。
FutureTask實現RunnableFuture接口,RunnableFuture繼承Runnable接口。所以newTaskFor(task, null)方法返回一個FutureTask對象。
public class FutureTaskimplements RunnableFuture public interface RunnableFuture extends Runnable, Future RunnableFuture ftask = newTaskFor(task, null); protected RunnableFuture newTaskFor(Runnable runnable, T value) { return new FutureTask (runnable, value); } public FutureTask(Runnable runnable, V result) { this.callable = Executors.callable(runnable, result); this.state = NEW; // ensure visibility of callable } public static Callable callable(Runnable task, T result) { if (task == null) throw new NullPointerException(); return new RunnableAdapter (task, result); } static final class RunnableAdapter implements Callable { final Runnable task; final T result; RunnableAdapter(Runnable task, T result) { this.task = task; this.result = result; } public T call() { task.run(); return result; } }
5.關鍵的調用ThreadPoolExecutor類execute方法,管理線程池并執行Runnable任務。主要邏輯如下:
1)如果線程數量小于corePoolSize,新來一個任務,創建一個新線程。
2)如果線程數量等于corePoolSize,則將任務緩存到workQueue中。
3)如果線程數量等于corePoolSize并且workQueue隊列已滿,則繼續創建線程直到等于maximumPoolSize。
4)如果線程數量等于maximumPoolSize,且workQueue隊列已滿,則根據defaultHandler策略執行相應措施。默認是AbortPolicy,拋出一個運行時異常RejectedExecutionException。另外還有3種策略:CallerRunsPolicy->如果線程池沒有shutdown,則直接調用Runnable的run方法執行。如果線程池shutdown,則直接丟棄;DiscardPolicy->直接丟棄,沒有任何異常;DiscardOldestPolicy->丟棄最老的任務,并調用線程池的execute方法執行,如果線程池沒有shutdown。
public void execute(Runnable command) { if (command == null) throw new NullPointerException(); int c = ctl.get(); if (workerCountOf(c) < corePoolSize) { if (addWorker(command, true)) return; c = ctl.get(); } if (isRunning(c) && workQueue.offer(command)) { int recheck = ctl.get(); if (! isRunning(recheck) && remove(command)) reject(command); else if (workerCountOf(recheck) == 0) addWorker(null, false); } else if (!addWorker(command, false)) reject(command); }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/69881.html
摘要:整個包,按照功能可以大致劃分如下鎖框架原子類框架同步器框架集合框架執行器框架本系列將按上述順序分析,分析所基于的源碼為。后,根據一系列常見的多線程設計模式,設計了并發包,其中包下提供了一系列基礎的鎖工具,用以對等進行補充增強。 showImg(https://segmentfault.com/img/remote/1460000016012623); 本文首發于一世流云專欄:https...
摘要:是目前的實驗收集器。也是需要暫停程序一切的工作,然后多線程執行垃圾回收。與最大的不同,它關注的是垃圾回收的吞吐量。這里的吞吐量指的是總時間與垃圾回收時間的比例。篩選回收,評估標記垃圾,根據模式回收垃圾。 《對象搜索算法與回收算法》介紹了垃圾回收的基礎算法,相當于垃圾回收的方法論。接下來就詳細看看垃圾回收的具體實現。 上文提到過現代的商用虛擬機的都是采用分代收集的,不同的區域用不同的收集...
摘要:本文主要內容為簡單總結中線程池的相關信息。方法簇方法簇用于創建固定線程數的線程池。三種常見線程池的對比上文總結了工具類創建常見線程池的方法,現對三種線程池區別進行比較。 概述 線程可認為是操作系統可調度的最小的程序執行序列,一般作為進程的組成部分,同一進程中多個線程可共享該進程的資源(如內存等)。在單核處理器架構下,操作系統一般使用分時的方式實現多線程;在多核處理器架構下,多個線程能夠...
摘要:為程序員金三銀四精心挑選的余道面試題與答案,歡迎大家向我推薦你在面試過程中遇到的問題我會把大家推薦的問題添加到下面的常用面試題清單中供大家參考。 為Java程序員金三銀四精心挑選的300余道Java面試題與答案,歡迎大家向我推薦你在面試過程中遇到的問題,我會把大家推薦的問題添加到下面的常用面試題清單中供大家參考。 前兩天寫的以下博客,大家比較認可,熱度不錯,希望可以幫到準備或者正在參加...
摘要:下面是線程相關的熱門面試題,你可以用它來好好準備面試。線程安全問題都是由全局變量及靜態變量引起的。持有自旋鎖的線程在之前應該釋放自旋鎖以便其它線程可以獲得自旋鎖。 最近看到網上流傳著,各種面試經驗及面試題,往往都是一大堆技術題目貼上去,而沒有答案。 不管你是新程序員還是老手,你一定在面試中遇到過有關線程的問題。Java語言一個重要的特點就是內置了對并發的支持,讓Java大受企業和程序員...
閱讀 2021·2019-08-30 15:52
閱讀 2975·2019-08-29 16:09
閱讀 1323·2019-08-28 18:30
閱讀 2453·2019-08-26 12:24
閱讀 1090·2019-08-26 12:12
閱讀 2273·2019-08-26 10:45
閱讀 565·2019-08-23 17:52
閱讀 810·2019-08-23 16:03