深入分析執行緒池(二)—ThreadPoolExecutor常用方法
詳細介紹ThreadPoolExecutor的方法:
- 方法shutdown() 和 shutdownNow()
shutdown :使當前未執行的執行緒繼續執行,而不再新增新的任務Task,該方法不會阻塞。
shutdownNow :
1. 當在Runnable中使用 if(Thread.currentThread.isInterruptd() == true)來判斷當前執行緒的中斷狀態,,中斷所有的任務task,並且丟擲InterruptedException異常,而未執行的執行緒不再執行,從任務佇列中清除。
2. 如果沒有if語句,則池中執行的執行緒直到執行完畢,而未執行的不再執行,從執行佇列佇列中刪除。
區別:
池子呼叫shutdown,池中狀態立馬變成SHUTDOWN狀態,此時再往池中新增任務,會觸發拒絕策略。此時池中不會立刻退出,直到池中的任務都已經完成,才會退出。
總之:呼叫後,正在執行的任務和佇列中的任務在後期正常執行,只是不再添加了。
池子呼叫shutdownNow,池中狀態立馬變成STOP狀態,並試圖停止所有正在執行的執行緒(除非有if判斷人為的丟擲異常),不再處理還在池佇列中等待的任務,會返還未執行的任務。
總之:呼叫,停止正在執行的,用一個llist<Runnable>佇列來儲存未執行的任務,並返回。
- isShutdown()
判斷執行緒池是否已經關閉,只要呼叫的shutdown()方法,則isShutdown()方法的返回值就是true。,
- isTerminating() 和 isTerminated()
前者是否正在關閉,但尚未完全終止的過程,返回true。
後者是已經關閉了。
- awaitTermination(long timeout, TimeUnit unit)
檢視在指定的時間內,池子是否已經終止工作,即最多等待多少時間後去判斷池子已經終止工作。
一般和shutdown()方法配合
如果池中有任務在被執行時,呼叫其方法會出現阻塞,等待指定的時間,如果沒有任務則不會出現阻塞。
所以這個方法和shutdown結合可以實現“等待執行完畢”的效果,就是因為其有阻塞性。
如果正在阻塞的時候,任務執行完畢,那麼該會取消阻塞繼續執行後面的程式碼。
public class test{
public static void main(String[] args) throws InterruptedException{
MyRunnable myrunnable = new MyRunnable();
ThreadPoolExecutor pool = new ThreadPoolExecutor(2,9999,9999L,
TimeUnit.SECONDS, new LinkedBlockingDeque<>());
pool.execute(myrunnable);
pool.shutdown();
System.out.println("begin");
// 阻塞10s(等待10s),如果改成1s,則是false,在4s之前就已經停止判斷了
System.out.println(pool.awaitTermination(10,TimeUnit.SECONDS));
System.out.println("end");
}
}
class MyRunnable implements Runnable{
@Override
public void run() {
try{
System.out.println(Thread.currentThread().getName()+ " " + System.currentTimeMillis());
Thread.sleep(4000); //睡眠4秒
System.out.println(Thread.currentThread().getName()+ " " + System.currentTimeMillis());
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
// 正在阻塞時,任務執行完畢,那麼會取消阻塞
public class test{
public static void main(String[] args) throws InterruptedException{
MyRunnable myrunnable = new MyRunnable();
ThreadPoolExecutor pool = new ThreadPoolExecutor(2,9999,9999L,
TimeUnit.SECONDS, new LinkedBlockingDeque<>());
pool.execute(myrunnable);
pool.execute(myrunnable);
pool.execute(myrunnable);
pool.execute(myrunnable);
pool.shutdown();
System.out.println(pool.awaitTermination(Integer.MAX_VALUE,
TimeUnit.SECONDS)+ " " + System.currentTimeMillis()+ "全部執行完畢");
}
}
class MyRunnable implements Runnable{
@Override
public void run() {
try{
System.out.println(Thread.currentThread().getName() + " "
+ System.currentTimeMillis());
Thread.sleep(1000);
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
- setThreadFactory方法+UncaughtExceptionHandler處理異常
對執行緒池建立的執行緒進行屬性定製化,當程式丟擲異常時,可以自定義處理。
除了用構造方法來傳遞自定義ThreadFactory外,還可以使用setThreadFactory來設定自定義的執行緒工廠。
public class Test{
public static void main(String[] args) {
MyThreadFactory mythreadFactory = new MyThreadFactory();
MyRunnable myrunnable = new MyRunnable();
ThreadPoolExecutor pool = new ThreadPoolExecutor(2,9999,9999L,
TimeUnit.SECONDS, new LinkedBlockingDeque<>(),mythreadFactory);
// 利用構造引數來傳入自定義的執行緒工廠
// pool.setThreadFactory(mythreadFactory); 完全可以用方法來傳入自定義執行緒工廠
pool.execute(myrunnable);
}}
class MyRunnable implements Runnable和上述一樣
class MyThreadFactory implements ThreadFactory {
@Override
public Thread newThread(Runnable r) {
Thread newthread = new Thread(r);
newthread.setName("wang" + new Date()); // 自定義工廠,如果出現異常是可以自定義處理的。
newthread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("自定義處理異常" + t.getName() + e.getMessage());
e.printStackTrace();
}
});
return newthread;
}}
- set/getRejectExecutionHandler()
可以處理任務被拒絕執行時的行動
public class Test{
public static void main(String[] args) {
MyRunnable myRunnable1 = new MyRunnable("wang1");
MyRunnable myRunnable2 = new MyRunnable("wang2");
MyRunnable myRunnable3 = new MyRunnable("wang3");
MyRunnable myRunnable4 = new MyRunnable("wang4");
//是直接提交的排隊策略,最大3個顯然會有一個拒絕
ThreadPoolExecutor pool = new ThreadPoolExecutor(2,3,9999L,
TimeUnit.SECONDS, new SynchronousQueue<>());
pool.setRejectedExecutionHandler(new MyRejectExecutionhandle()); //實現自定義拒絕策略
pool.execute(myRunnable1);
pool.execute(myRunnable2);
pool.execute(myRunnable3);
pool.execute(myRunnable4);
}
}
class MyRejectExecutionhandle implements RejectedExecutionHandler{
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
System.out.println(((MyRunnable)r).getUsername() + "被拒絕了");
}
}
class MyRunnable implements Runnable{
private String username;
public MyRunnable(String username){
super();
this.username = username;
}
public String getUsername(){return username;}
public void setUsername(String username){
this.username = username;
}
@Override
public void run() {
try{
System.out.println(Thread.currentThread().getName()+ " " + System.currentTimeMillis());
Thread.sleep(4000); //睡眠4秒
System.out.println(Thread.currentThread().getName()+ " " + System.currentTimeMillis());
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
- prestartCoreThread() 和 prestartAllCoreThreads()
前者每次呼叫一次就建立一個核心執行緒,返回的是boolean
後者啟動全部核心執行緒,返回的是啟動核心執行緒的數量 - remove(Runnable)
可以刪除尚未被執行的Runnable任務。 - 多個get方法
getActiveCount() : 取得多少個執行緒正在執行的任務
getPoolSize() : 當前池中裡面有多少個執行緒,包括正在執行任務的執行緒,也包括在休眠的執行緒
getCompletedTaskCount() :取得已經執行完成的任務數
getCorePoolSize() : 取的構造方法傳入的corePoolSize引數值
getMaximumPoolSize() : 取的構造方法中MaximumPoolSize的引數值
getPoolSize() : 取的池中有多少個執行緒
getTaskCount() : 取得有多少個任務傳送給了執行緒池,執行的+ 排隊的
有一點要注意: 介面Runnable在ThreadPooExecutor佇列中是按順序取出的,執行卻是亂序的。
相關推薦
深入分析執行緒池(二)—ThreadPoolExecutor常用方法
這4個類就是我們的主線。這裡我只顯示了public方法詳細介紹ThreadPoolExecutor的方法:方法shutdown() 和 shutdownNow() shutdown :使當前未執行的執行緒繼續執行,而不再新增新的任務Task,該方法不會阻塞。 sh
Java多執行緒之執行緒池(二)
java.util.concurrent包是jdk1.5以後使用的執行緒庫,在jdk1.5之前主要使用java.lang和java.util中的類實現 package three.day.thread; import java.util.Random; import ja
Java併發包原始碼學習之執行緒池(一)ThreadPoolExecutor原始碼分析
Java中使用執行緒池技術一般都是使用Executors這個工廠類,它提供了非常簡單方法來建立各種型別的執行緒池: public static ExecutorService newFixedThreadPool(int nThreads) public static ExecutorService
Android執行緒池(四)ThreadPoolExecutor類原始碼解析
使用ThreadPoolExecutor private final int CORE_POOL_SIZE = 4;//核心執行緒數 private final int MAX_POOL_SIZE = 5;//最大執行緒數 priv
深入理解Java多執行緒--執行緒池(ThreadPool)
在java多執行緒開發中,我們需要使用執行緒的時候一般是建立一個Thread物件,然後呼叫start()方法去執行執行緒操作。這樣做沒有什麼問題,但是如果我們有很多工需要多個執行緒來非同步執行的時候,在我們建立了很多執行緒的情況下,會造成很大的效能方面的問題。 1.大量的執行緒的建立和銷燬,
java併發學習--執行緒池(一)
關於java中的執行緒池,我一開始覺得就是為了避免頻繁的建立和銷燬執行緒吧,先建立一定量的執行緒,然後再進行復用。但是要具體說一下如何做到的,自己又說不出一個一二三來了,這大概就是自己的學習習慣流於表面,不經常深入的結果吧。所以這裡決定系統的學習一下執行緒池的相關知識。 自己稍微總結了一下,
java多執行緒之(二)鎖
一,鎖 在物件的建立時java會為每個object物件分配一個monitor( 監視器或者監視鎖),當某個物件的同步方法(synchronized methods )被多個執行緒呼叫時,該物件的monitor將負責處理這些訪問的併發獨佔要求。 當一個執行緒呼叫一個物件的同步方法時(sy
JAVA執行緒總結( 二)
繼續上篇的總結,這次我們講執行緒同步機制 執行緒同步是為了確保執行緒安全,所謂執行緒安全指的是多個執行緒對同一資源進行訪問時,有可能產生資料不一致問題,導致執行緒訪問的資源並不是安全的。如果多執行緒程式執行結果和單執行緒執行的結果是一樣的,且相關變數的值與預期值一樣,則是執行緒安全的。
Java多執行緒之執行緒排程(二)
(一)執行緒優先順序 執行緒優先順序用1~10表示,10表示優先順序最高,預設值是5.每個優先順序對應一個Thread類的公用靜態常量。如 public static final int MIN_PRIORITY = 1; public static final int NO
python執行緒池(threadpool)模組使用筆記
https://www.cnblogs.com/xiaozi/p/6182990.html 一、安裝與簡介 pip install threadpool pool = ThreadPool(poolsize) requests = make
linux多執行緒入門(二)互斥量
當多個執行緒訪問一個共享的變數的時候是非常危險的,可能會拿到錯誤的資料或者程式崩潰! 所以為了安全的使用執行緒引入了互斥量的做法 兩個互斥量的函式為 pthread_mutex_lock(pthread_mutex_lock* lock) pthread_mutex_unlock(p
java多執行緒-初探(二)
java多執行緒-初探(一) 常見的執行緒函式 sleep 當前執行緒暫停 join 加入到當前執行緒中 setPriority 執行緒優先順序
java執行緒池(newCachedThreadPool)的使用
import java.util.concurrent.*; /** * java執行緒池的使用 * 這個【可快取執行緒池】,沒看出來有什麼用呢。。。 */ public class Exe
Linux學習之多執行緒程式設計(二)
言之者無罪,聞之者足以戒。 ——《詩序》 (二)、執行緒的基本控制 1、終止程序: 如果程序中的任意一個程序呼叫了exit、_exit、_Exit,那麼整個程序就會終止 普通的單個程序有以下3種退出方式,這樣不會終止程序: (1)從啟動例程中返回,返回值是執行緒的退
程序管理實驗——POSIX下執行緒控制(二)
實驗目的 1、通過觀察、分析實驗現象,深入理解執行緒及執行緒在排程執行和記憶體空間等方面的特點,並掌握執行緒與程序的區別。 2、掌握在POSIX 規範中pthread_create() 函式的功能和
ExecutorService 執行緒池 (轉發)
1.ExecutorService java.util.concurrent.ExecutorService 介面。用來設定執行緒池並執行多執行緒任務。它有以下幾個方法。 Future<?> java.util.concurrent.ExecutorServ
執行緒池(三)
執行緒池(三)主要介紹執行緒池如何根據不同的場景配置,及簡單的使用示例。如有不正確之處,請斧正,謝謝! 一、配置場景 執行緒池初始化引數:corePoolSize,maxMumPoolSize,keepAlivetime,TimeUnit,ThreadFactory,BlockingQu
執行緒執行者(二)建立一個執行緒執行者
宣告:本文是《 Java 7 Concurrency Cookbook 》的第四章,作者: Javier Fernández González 譯者:許巧輝 校對:方騰飛 建立一個執行緒執行者 使用Executor framework的第一步就是建立一個ThreadPoolEx
執行緒管理(二)獲取和設定執行緒資訊
宣告:本文是《 Java 7 Concurrency Cookbook 》的第一章, 作者: Javier Fernández González 譯者:鄭玉婷 校對:歐振聰 獲取和設定執行緒資訊 Thread類的物件中儲存了一些屬性資訊能夠幫助我們來辨別每一個執行緒,知道它的狀態,調整控制其優
基本執行緒同步(二)同步方法
宣告:本文是《 Java 7 Concurrency Cookbook 》的第二章,作者: Javier Fernández González 譯者:許巧輝 校對:方騰飛 同步方法 在這個指南中,我們將學習在Java中如何使用一個最基本的同步方法,即使用 synchronized關鍵字