【經典】JAVA線程池

JAVA多線程的五個狀態:

Running:運行態,該狀態下線程池能夠接受新的任務

Shutdown:該狀態下不接受新的任務,但會繼續處理已經添加的任務。

Stop:該狀態下不接受新的任務,並且會中斷正在執行的任務,同時刪除未處理的任務;

Tidying:指當前所有的任務已經停止;

Terminated:該狀態表示線程池徹底停止。

 

多線程創建方法一

JAVA中我們用JUC包下的ThreadPoolExecutor來創建線程池,ThreadPoolExecutor提供了四個構造方法:

public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue)


public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory)


public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler)


public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)

其中:

corePoolSize:指線程池的容量大小;如果調用prestartAllCoreThreads(),則會提前初始化所以線程。

maximumPoolSize:指線程最大數;如果corePoolSize滿時會創建線程直到線程數等於maximumPoolSize;如果線程數等於maximumPoolSize後,下一個任務將被添加到線程等待隊列(第五個參數);

keepAliveTime:指線程存活時間

timeUnit:存活時間的單位

BlockingQueue<Runnable> workQueue:線程等待隊列類型;

BlockingQueue,有以下幾種

ArrayBlockingQueue,必須制定長度,其底層只用一個鎖,同一時間點上,只能有一個入隊或出隊的操作;

LinkedBlockingQueue,默認長度的Integer的最大值,底層維護着兩把鎖,一個用於入隊,一個用於出隊;

SynchronousQueue, 沒有容量的無緩衝等待隊列,當有任務時它直接將任務交給消費者。

DelayedWordQueue, 無界的延時隊列,即可以指定隊列裏的任務被延時消費。

依據數組和鏈接的特點,可以適當選擇;

因爲很多業務都是出入隊列高併發,所以大多數情況下,LinkedBlockingQueue一般情況下效率比ArrayBlockingQueue效率高;

ThreadFactory:線程工程,在創建線程時候用到;可以通過Executors.defaulThreadFactory()獲取;

RejectedExecutionHandler:拒絕策略;當線程隊列滿時(線程大於maximunPoolSize,且workQueue滿時),新進來的任務要這麼處理;默認是AbortPolicy,即直接拋異常;

RejectedExecutionHandler包含:

       1、AbortPolicy,默認的拒絕策略,即拋異常;

       2、CallerRunsPolicy,調用者所在的線程來執行,不一定是主線程,有可能是線程掉線程;

       3、DiscardOldestPolicy,丟棄隊列中最老的任務,並執行當前任務;

       4、DiscardPolicy,直接丟棄新任務;

拒絕策略是ThreadPoolExecutor的內部類,需要時使用,new ThreadPoolExecutor.AbortPolicy();

也可以自定義拒絕策略:實現RejectedExecutionHandler;

 

 多線程的創建方法二

  該方式也是官方推薦的:

 FixedThreadPool:必須指定線程數CoreSize,coreSize==maximumPoolSize ,底層用的是基於鏈表的隊列;

  Executors.newFixedThreadPool(int coreSize) : 

  Executors.newFixedThreadPool(int coreSize, ThreadFactory threadFacotry)

 

  CachedThreadPool: 默認coreSize=0;maximumPoolSize=Integer.MAX_VALUE; 底層是SychronousQueue無緩衝隊列

  Executors.newCachedThreadPool(); 

  Executors.newCachedThreadPool(ThreadFactory threadFacory);

 

 ScheduledThreadPool:必須指定coreSize;  maximumPoolSize=Integer.MAX_VALUE;底層使用的是DelayedWorkQueue延遲隊列。

 Executors.newScheduledThreadPool(int coreSize);

 Executors.newScheduledThreadPool(int coreSize, ThreadFactory threadFactory);

 

SingleThreadExecutor:和FixedThreadPool一樣,只是coreSize=1;(不常用)

SingleThreadScheduledExecutor:即是延時單例的;(不常用)

 

  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章