摘要:線程池的作用線程池能有效的處理多個線程的并發問題,避免大量的線程因為互相強占系統資源導致阻塞現象,能夠有效的降低頻繁創建和銷毀線程對性能所帶來的開銷。固定的線程數由系統資源設置。線程池的排隊策略與有關。線程池的狀態值分別是。
線程池的作用
線程池能有效的處理多個線程的并發問題,避免大量的線程因為互相強占系統資源導致阻塞現象,能夠有效的降低頻繁創建和銷毀線程對性能所帶來的開銷。
線程池的真相真正線程池的實現是通過ThreadPoolExecutor,ThreadPoolExecutor通過配置不同的參數配置來創建線程池。下面簡單的介紹一下各個線程池的區別和用處。
fixThreadPool 固定線程池Executor executor = Executors.newFixedThreadPool(10);
public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue()); }
我的理解這是一個有指定的線程數的線程池,有核心的線程,里面有固定的線程數量,響應的速度快。固定的線程數由系統資源設置。
注:核心線程是沒有超時機制的,隊列大小沒有限制,除非線程池關閉了核心線程才會被回收。
CacheThreadPool 緩存線程池Executor executor = Executors.newCachedThreadPool();
public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue()); }
構造方法解釋:只有非核心線程,最大線程數很大(Int.Max(values)),它會為每一個任務添加一個新的線程,這邊有一個超時機制,當空閑的線程超過60s內沒有用到的話,就會被回收。缺點就是沒有考慮到系統的實際內存大小。
SingleThreadPool 單線程線程池Executor executor = Executors.newSingleThreadExecutor();
public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue())); }
private final ExecutorService e; DelegatedExecutorService(ExecutorService executor) { e = executor; }
看這個名字就知道這個家伙是只有一個核心線程,底層還進行了封裝。但其實就是只是將線程池的應用加了final關鍵字
ScheduledThreadPoolExecutors.newScheduledThreadPool(10);
public ScheduledThreadPoolExecutor(int corePoolSize) { super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS, new DelayedWorkQueue()); }
這個線程池就厲害了,是唯一一個有延遲執行和周期重復執行的線程池。它的核心線程池固定,非核心線程的數量沒有限制,但是閑置時會立即會被回收。
線程池最核心方法public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueueworkQueue) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,Executors.defaultThreadFactory(), defaultHandler); }
這個方法是所有線程池調用的最底層方法。總共有7個參數(面試曾問過參數的含義)
核心池的大小,,線程池默認創建的線程數。除非線程池銷毀,否則就不會銷毀
線程池最大線程數,它表示在線程池中最多能創建多少個線程;
表示線程沒有任務執行時最多保持多久時間會終止。默認情況下,只有當線程池中的線程數大于corePoolSize時,keepAliveTime才會起作用,直到線程池中的線程數不大于corePoolSize,即當線程池中的線程數大于corePoolSize時,如果一個線程空閑的時間達到keepAliveTime,則會終止,直到線程池中的線程數不超過corePoolSize。但是如果調用了allowCoreThreadTimeOut(boolean)方法,在線程池中的線程數不大于corePoolSize時,keepAliveTime參數也會起作用,直到線程池中的線程數為0;
參數keepAliveTime的時間單位,有7種取值,在TimeUnit類中有7種靜態屬性:
TimeUnit.DAYS; //天
TimeUnit.HOURS; //小時
TimeUnit.SECONDS; //秒
TimeUnit.MILLISECONDS; //毫秒
TimeUnit.MICROSECONDS; //微妙
TimeUnit.NANOSECONDS; //納秒
一個阻塞隊列,用來存儲等待執行的任務,這個參數的選擇也很重要,會對線程池的運行過程產生重大影響,一般來說,這里的阻塞隊列有以下幾種選擇:
ArrayBlockingQueue:基于數組的先進先出隊列,此隊列創建時必須指定大小;
LinkedBlockingQueue:基于鏈表的先進先出隊列,如果創建時沒有指定此隊列大小,則默認為Integer.MAX_VALUE;
synchronousQueue:這個隊列比較特殊,它不會保存提交的任務,而是將直接新建一個線程來執行新來的任務。
ArrayBlockingQueue和PriorityBlockingQueue使用較少,一般使用LinkedBlockingQueue和Synchronous。線程池的排隊策略與BlockingQueue有關。
線程工廠,主要用來創建線程;
表示當拒絕處理任務時的策略,有以下四種取值:
ThreadPoolExecutor.AbortPolicy:丟棄任務并拋出RejectedExecutionException異常。 ThreadPoolExecutor.DiscardPolicy:也是丟棄任務,但是不拋出異常。 ThreadPoolExecutor.DiscardOldestPolicy:丟棄隊列最前面的任務,然后重新嘗試執行任務(重復此過程) ThreadPoolExecutor.CallerRunsPolicy:由調用線程處理該任務線程池家族譜
ExecutorService extend Executor AbstractExecutorService implements ExecutorService ThreadPoolExecutor extends AbstractExecutorService
Executor是一個頂層接口,在它里面只聲明了一個方法execute(Runnable),返回值為void,參數為Runnable類型,從字面意思可以理解,就是用來執行傳進去的任務的;
然后ExecutorService接口繼承了Executor接口,并聲明了一些方法:submit、invokeAll、invokeAny以及shutDown等;
抽象類AbstractExecutorService實現了ExecutorService接口,基本實現了ExecutorService中聲明的所有方法;
然后ThreadPoolExecutor繼承了類AbstractExecutorService。
線程池的狀態private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0)); // runState is stored in the high-order bits private static final int RUNNING = -1 << COUNT_BITS; private static final int SHUTDOWN = 0 << COUNT_BITS; private static final int STOP = 1 << COUNT_BITS; private static final int TIDYING = 2 << COUNT_BITS; private static final int TERMINATED = 3 << COUNT_BITS;
值分別是。-1,0,1,2,3,
當創建線程池后,初始時,線程池處于RUNNING狀態;
如果調用了shutdown()方法,則線程池處于SHUTDOWN狀態,此時線程池不能夠接受新的任務,它會等待所有任務執行完畢;
如果調用了shutdownNow()方法,則線程池處于STOP狀態,此時線程池不能接受新的任務,并且會去嘗試終止正在執行的任務;
當線程池處于SHUTDOWN或STOP狀態,并且所有工作線程已經銷毀,任務緩存隊列已經清空或執行結束后,線程池被設置為TERMINATED狀態。
線程池的重要變量private final BlockingQueueworkQueue; //任務緩存隊列,用來存放等待執行的任務 private final ReentrantLock mainLock = new ReentrantLock(); //線程池的主要狀態鎖,對線程池狀態(比如線程池大小 //、runState等)的改變都要使用這個鎖 private final HashSet workers = new HashSet (); //用來存放工作集 private volatile long keepAliveTime; //線程存活時間 private volatile boolean allowCoreThreadTimeOut; //是否允許為核心線程設置存活時間 private volatile int corePoolSize; //核心池的大小(即線程池中的線程數目大于這個參數時,提交的任務會被放進任務緩存隊列) private volatile int maximumPoolSize; //線程池最大能容忍的線程數 private volatile int poolSize; //線程池中當前的線程數 private volatile RejectedExecutionHandler handler; //任務拒絕策略 private volatile ThreadFactory threadFactory; //線程工廠,用來創建線程 private int largestPoolSize; //用來記錄線程池中曾經出現過的最大線程數 private long completedTaskCount; //用來記錄已經執行完畢的任務個數
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/69579.html
摘要:當活動線程核心線程非核心線程達到這個數值后,后續任務將會根據來進行拒絕策略處理。線程池工作原則當線程池中線程數量小于則創建線程,并處理請求。當線程池中的數量等于最大線程數時默默丟棄不能執行的新加任務,不報任何異常。 spring-cache使用記錄 spring-cache的使用記錄,坑點記錄以及采用的解決方案 深入分析 java 線程池的實現原理 在這篇文章中,作者有條不紊的將 ja...
摘要:源碼分析創建可緩沖的線程池。源碼分析使用創建線程池源碼分析的構造函數構造函數參數核心線程數大小,當線程數,會創建線程執行最大線程數,當線程數的時候,會把放入中保持存活時間,當線程數大于的空閑線程能保持的最大時間。 之前創建線程的時候都是用的 newCachedThreadPoo,newFixedThreadPool,newScheduledThreadPool,newSingleThr...
摘要:對線程池的研究是之前對分析的附加工作。在之前對源碼分析的文章中,寫到調度器將任務放入線程池的函數這里分析的線程池類是,也就是上述代碼中所使用的類。 對Python線程池的研究是之前對Apshceduler分析的附加工作。 在之前對Apshceduler源碼分析的文章中,寫到調度器將任務放入線程池的函數 def _do_submit_job(self, job, run_time...
摘要:任務性質不同的任務可以用不同規模的線程池分開處理。線程池在運行過程中已完成的任務數量。如等于線程池的最大大小,則表示線程池曾經滿了。線程池的線程數量。獲取活動的線程數。通過擴展線程池進行監控。框架包括線程池,,,,,,等。 Java線程池 [toc] 什么是線程池 線程池就是有N個子線程共同在運行的線程組合。 舉個容易理解的例子:有個線程組合(即線程池,咱可以比喻為一個公司),里面有3...
摘要:線程池常見實現線程池一般包含三個主要部分調度器決定由哪個線程來執行任務執行任務所能夠的最大耗時等線程隊列存放并管理著一系列線程這些線程都處于阻塞狀態或休眠狀態任務隊列存放著用戶提交的需要被執行的任務一般任務的執行的即先提交的任務先被執行調度 線程池常見實現 線程池一般包含三個主要部分: 調度器: 決定由哪個線程來執行任務, 執行任務所能夠的最大耗時等 線程隊列: 存放并管理著一系列線...
閱讀 1804·2023-04-26 02:32
閱讀 567·2021-11-18 13:12
閱讀 2446·2021-10-20 13:48
閱讀 2515·2021-10-14 09:43
閱讀 3825·2021-10-11 10:58
閱讀 3483·2021-09-30 10:00
閱讀 2932·2019-08-30 15:53
閱讀 3487·2019-08-30 15:53