1. 程式人生 > >深入分析執行緒池(二)—ThreadPoolExecutor常用方法

深入分析執行緒池(二)—ThreadPoolExecutor常用方法

這4個類就是我們的主線。這裡我只顯示了public方法

詳細介紹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關鍵字