1. 程式人生 > >執行緒池Executors.newFixedThreadPool

執行緒池Executors.newFixedThreadPool

Sun在Java5中,對Java執行緒的類庫做了大量的擴充套件,其中執行緒池就是Java5的新特徵之一,除了執行緒池之外,還有很多多執行緒相關的內容,為多執行緒的程式設計帶來了極大便利。為了編寫高效穩定可靠的多執行緒程式,執行緒部分的新增內容顯得尤為重要。 

執行緒池的概念:

執行緒池的基本思想還是一種物件池的思想,開闢一塊記憶體空間,裡面存放了眾多(未死亡)的執行緒,池中執行緒執行排程由池管理器來處理。當有執行緒任務時,從池中取一個,執行完成後執行緒物件歸池,這樣可以避免反覆建立執行緒物件所帶來的效能開銷,節省了系統的資源。 

(舉個簡單的例子,執行緒池就相當於一個水池又或者是一個筆筒,裡面放著很多的筆,當有執行緒任務的時候,就從筆筒去除,用完之後就再次放入進去。)

個人理解:

1、在Java5之前,要實現一個執行緒池是相當有難度的,現在Java5為我們做好了一切,我們只需要按照提供的API來使用,即可享受執行緒池帶來的極大便利。 

2、Java5的執行緒池分好多種:具體的可以分為兩類,固定尺寸的執行緒池、可變尺寸連線池。 

3、在使用執行緒池之前,必須知道如何去建立一個執行緒池,在Java5中,需要了解java.util.concurrent.Executors類的API,這個類提供大量建立連線池的靜態方法,是必須掌握的。


一、固定大小的執行緒池,newFixedThreadPool:

  1. package app.executors;  
  2. import java.util.concurrent.Executors;  
  3. import java.util.concurrent.ExecutorService;  
  4. /** 
  5.  * Java執行緒:執行緒池 
  6.  *  
  7.  * @author 馮小衛 
  8.  */
  9. publicclass Test {  
  10.     publicstaticvoid main(String[] args) {  
  11.         // 建立一個可重用固定執行緒數的執行緒池
  12.         ExecutorService pool = Executors.newFixedThreadPool(5);  
  13.         // 建立執行緒
  14.         Thread t1 = new MyThread();  
  15.         Thread t2 = new MyThread();  
  16.         Thread t3 = new MyThread();  
  17.         Thread t4 = new MyThread();  
  18.         Thread t5 = new MyThread();  
  19.         // 將執行緒放入池中進行執行
  20.         pool.execute(t1);  
  21.         pool.execute(t2);  
  22.         pool.execute(t3);  
  23.         pool.execute(t4);  
  24.         pool.execute(t5);  
  25.         // 關閉執行緒池
  26.         pool.shutdown();  
  27.     }  
  28. }  
  29. class MyThread extends Thread {  
  30.     @Override
  31.     publicvoid run() {  
  32.         System.out.println(Thread.currentThread().getName() + "正在執行。。。");  
  33.     }  
  34. }  


輸出結果:

  1. pool-1-thread-1正在執行。。。  
  2. pool-1-thread-3正在執行。。。  
  3. pool-1-thread-4正在執行。。。  
  4. pool-1-thread-2正在執行。。。  
  5. pool-1-thread-5正在執行。。。  


改變ExecutorService pool = Executors.newFixedThreadPool(5)中的引數:ExecutorService pool = Executors.newFixedThreadPool(2),輸出結果是:

  1. pool-1-thread-1正在執行。。。  
  2. pool-1-thread-1正在執行。。。  
  3. pool-1-thread-2正在執行。。。  
  4. pool-1-thread-1正在執行。。。  
  5. pool-1-thread-2正在執行。。。  


從以上結果可以看出,newFixedThreadPool的引數指定了可以執行的執行緒的最大數目,超過這個數目的執行緒加進去以後,不會執行。其次,加入執行緒池的執行緒屬於託管狀態,執行緒的執行不受加入順序的影響。

二、單任務執行緒池,newSingleThreadExecutor:

僅僅是把上述程式碼中的ExecutorService pool = Executors.newFixedThreadPool(2)改為ExecutorService pool = Executors.newSingleThreadExecutor();

輸出結果:

  1. pool-1-thread-1正在執行。。。  
  2. pool-1-thread-1正在執行。。。  
  3. pool-1-thread-1正在執行。。。  
  4. pool-1-thread-1正在執行。。。  
  5. pool-1-thread-1正在執行。。。  

可以看出,每次呼叫execute方法,其實最後都是呼叫了thread-1的run方法。

三、可變尺寸的執行緒池,newCachedThreadPool:

與上面的類似,只是改動下pool的建立方式:ExecutorService pool = Executors.newCachedThreadPool();


輸出:

  1. pool-1-thread-1正在執行。。。  
  2. pool-1-thread-2正在執行。。。  
  3. pool-1-thread-4正在執行。。。  
  4. pool-1-thread-3正在執行。。。  
  5. pool-1-thread-5正在執行。。。  


這種方式的特點是:可根據需要建立新執行緒的執行緒池,但是在以前構造的執行緒可用時將重用它們。

四、延遲連線池,newScheduledThreadPool:

  1. package app.executors;  
  2. import java.util.concurrent.Executors;  
  3. import java.util.concurrent.ScheduledExecutorService;  
  4. import java.util.concurrent.TimeUnit;  
  5. /** 
  6.  * Java執行緒:執行緒池 
  7.  *  
  8.  * @author 馮小衛 
  9.  */
  10. publicclass Test {  
  11.     publicstaticvoid main(String[] args) {  
  12.         // 建立一個執行緒池,它可安排在給定延遲後執行命令或者定期地執行。
  13.         ScheduledExecutorService pool = Executors.newScheduledThreadPool(2);  
  14.         // 建立實現了Runnable介面物件,Thread物件當然也實現了Runnable介面
  15.         Thread t1 = new MyThread();  
  16.         Thread t2 = new MyThread();  
  17.         Thread t3 = new MyThread();  
  18.         // 將執行緒放入池中進行執行
  19.         pool.execute(t1);  
  20.         // 使用延遲執行風格的方法
  21.         pool.schedule(t2, 1000, TimeUnit.MILLISECONDS);  
  22.         pool.schedule(t3, 10, TimeUnit.MILLISECONDS);  
  23.         // 關閉執行緒池
  24.         pool.shutdown();  
  25.     }  
  26. }  
  27. class MyThread extends Thread {  
  28.     @Override
  29.     publicvoid run() {  
  30.         System.out.println(Thread.currentThread().getName() + "正在執行。。。");  
  31.     }  
  32. }  


讀者可以嘗試改變Executors.newScheduledThreadPool(2)的引數來得到更多的體驗,當然,讓

  1. @Override
  2. publicvoid run() {  
  3.     System.out.println(Thread.currentThread().getName() + "正在執行。。。");  
  4. }  

1、ExecutorService:

是一個介面,繼承了Executor:

public interface ExecutorService extends Executor {
}
2、Executor:

而Executor亦是一個介面,該介面只包含了一個方法:

void execute(Runnable command);
3、Executors:

該類是一個輔助類,此包中所定義的 Executor、ExecutorService、ScheduledExecutorService、ThreadFactory 和 Callable 類的工廠和實用方法。

此類支援以下各種方法:

• 建立並返回設定有常用配置字串的 ExecutorService 的方法。
• 建立並返回設定有常用配置字串的 ScheduledExecutorService 的方法。
• 建立並返回“包裝的”ExecutorService 方法,它通過使特定於實現的方法不可訪問來禁用重新配置。
• 建立並返回 ThreadFactory 的方法,它可將新建立的執行緒設定為已知的狀態。
• 建立並返回非閉包形式的 Callable 的方法,這樣可將其用於需要 Callable 的執行方法中。 4、建立ExecutorService的方法:
newFixedThreadPool()

建立一個可重用固定執行緒數的執行緒池,以共享的無界佇列方式來執行這些執行緒。

5、ExecutorService的方法:

shutdown

void shutdown()
啟動一次順序關閉,執行以前提交的任務,但不接受新任務。如果已經關閉,則呼叫沒有其他作用。 
丟擲:
 - 如果安全管理器存在並且關閉,此 ExecutorService 可能操作某些不允許呼叫者修改的執行緒(因為它沒有保持 RuntimePermission("modifyThread")),或者安全管理器的 checkAccess 方法拒絕訪問。

啟動一次順序關閉,執行以前提交的任務,但不接受新任務。如果已經關閉,則呼叫沒有其他作用。

awaitTermination

boolean awaitTermination(long timeout,
                         TimeUnit unit)
                         throws InterruptedException
請求關閉、發生超時或者當前執行緒中斷,無論哪一個首先發生之後,都將導致阻塞,直到所有任務完成執行。 
引數:
timeout - 最長等待時間
unit - timeout 引數的時間單位
返回:
如果此執行程式終止,則返回 true;如果終止前超時期滿,則返回 false
丟擲:

請求關閉、發生超時或者當前執行緒中斷,無論哪一個首先發生之後,都將導致阻塞,直到所有任務完成執行。既是等待所有子執行緒執行結束。

execute

void execute(Runnable command)
在未來某個時間執行給定的命令。該命令可能在新的執行緒、已入池的執行緒或者正呼叫的執行緒中執行,這由 Executor實現決定。 

在未來某個時間執行給定的命令。該命令可能在新的執行緒、已入池的執行緒或者正呼叫的執行緒中執行,這由 Executor 實現決定。

submit

提交一個 Runnable 任務用於執行,並返回一個表示該任務的 Future。該 Future 的 get 方法在成功 完成時將會返回null。 

提交一個 Runnable 任務用於執行,並返回一個表示該任務的 Future。該 Future 的 get 方法在成功 完成時將會返回 null。

6、下面是相關的使用例子:
public class ExecutorServiceTest {

    public static void main(String[] args) throws IOException, InterruptedException {
        // 建立一個固定大小的執行緒池
        ExecutorService service = Executors.newFixedThreadPool(3);
        for (int i = 0; i < 10; i++) {
            System.out.println("建立執行緒" + i);
            Runnable run = new Runnable() {
                @Override
                public void run() {
                    System.out.println("啟動執行緒");
                }
            };
            // 在未來某個時間執行給定的命令
            service.execute(run);
        }
        // 關閉啟動執行緒
        service.shutdown();
        // 等待子執行緒結束,再繼續執行下面的程式碼
        service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
        System.out.println("all thread complete");
    }
}

可以發現執行緒被迴圈建立,但是啟動執行緒卻不是連續的,而是由ExecutorService決定的。


相關推薦

執行Executors.newFixedThreadPool驗證以及總結

1、Executors在於java.util.comcurrent.包下,Executors.newFixedThreadPool(n)建立容器大小為n的執行緒池,表示正在執行中的執行緒只有n個, 實踐程式碼如下: public class TestExecute { public

執行Executors.newFixedThreadPool

Sun在Java5中,對Java執行緒的類庫做了大量的擴充套件,其中執行緒池就是Java5的新特徵之一,除了執行緒池之外,還有很多多執行緒相關的內容,為多執行緒的程式設計帶來了極大便利。為了編寫高效穩定可靠的多執行緒程式,執行緒部分的新增內容顯得尤為重要。  執行緒池的概

Java自帶的執行Executors.newFixedThreadPool

  執行緒池的基本思想還是一種物件池的思想,開闢一塊記憶體空間,裡面存放了眾多(未死亡)的執行緒,池中執行緒執行排程由池管理器來處理。當有執行緒任務時,從池中取一個,執行完成後執行緒物件歸池,這樣可以避免反覆建立執行緒物件所帶來的效能開銷,節省了系統的資源。    在Jav

Java四種執行newCachedThreadPool,newFixedThreadPool,newScheduledThreadPool,newSingle

轉自:https://www.cnblogs.com/baizhanshi/p/5469948.html 1、new Thread的弊端 執行一個非同步任務你還只是如下new Thread嗎? Java   1 2 3 4 5 6 7

java 執行 Executors 及 ThreadPoolExecutor

Java通過Executors提供四種執行緒池,分別為:  newCachedThreadPool建立一個可快取執行緒池,如果執行緒池長度超過處理需要,可靈活回收空閒執行緒,若無可回收,則新建執行緒。  newFixedThreadPool 建立一個定長執行緒池,可控制執行緒最大併發數,超出的執行緒會在佇列

執行 Executors

import static java.util.concurrent.TimeUnit.NANOSECONDS; import java.util.concurrent.AbstractExecutorService; import java.util.concurrent.ExecutorSe

自定義執行Executors

在使用有界佇列時,若有新的任務需要執行,如果執行緒池實際執行緒數小於corePoolSize,則優先建立執行緒,若大於corePoolSize,則會將任務加入佇列,若佇列已滿,則在匯流排程數不大於maximumPoolSize的前提下,建立新的執行緒,若執行緒數

JAVA執行--Executors之什麼是執行,為什麼使用執行以及執行的使用

1. 為什麼需要執行緒池?      多執行緒技術主要解決處理器單元內多個執行緒執行的問題,它可以顯著減少處理器單元的閒置時間,增加處理器單元的吞吐能力。              假設一個伺服器完成一項任務所需時間為:T1 建立執行緒時間,T2 線上程中執行任務的時間,T

Java多執行-執行Executors

概覽 通過上一篇對ThreadPoolExecutor的構造方法分析可以感受到,通過ThreadPoolExecutor來建立執行緒池是比較複雜的,引數比較多,考慮因素也多。 因此java自己提供了一個工廠類Executors,裡面提供了一些方法,用

JAVA併發程式設計:執行Executors

Java中對執行緒池提供了很好的支援,有了執行緒池,我們就不需要自已再去建立執行緒。如果併發的執行緒數量很多,並且每個執行緒都是執行一個時間很短的任務就結束了,頻繁建立執行緒就會大大降低系統的效率,因為頻繁建立執行緒和銷燬執行緒需要時間。JAVA的執行緒池中的執行緒可以在執

執行newFixedThreadPool定長執行

newFixedThreadPool建立一個定長執行緒池,可控制執行緒最大併發數,超出的執行緒會在佇列中等待。newFixedThreadPool固定執行緒池,  使用完畢必須手動關閉執行緒池, 否則會一直在記憶體中存在。示例程式碼:public class ThreadPo

java.util.concurrent包中執行Executors的使用

執行緒池的概念與Executors類的使用 (1)建立固定大小的執行緒池–當有多個任務時,會先按照執行緒池中的資料執行任務,其他任務處於等待過程中,等執行完這批任務後再執行下批任務。 (2)建立快

執行 JDK1.5 ExecutorService threadPool = Executors.newFixedThreadPool(3)

package cn.itcast.heima2; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit;

執行Executors中的newSingleThreadExecutor和newFixedThreadPool(1)的區別

在上一篇【執行緒池】深入理解Executors類時,提到了newSingleThreadExecutor和newFixedThreadPool(1)的區別,查閱了大量資料,自己也做了一些實驗,但是還是有很多不清楚的地方,這篇文章主要是用作討論,如果有大佬有好的回答,拜託請多多

java併發:Executors可以建立的三個執行

Executors.newSingleThreadExecutor();  建立一個單執行緒池,裡面維護了一個佇列.如果在執行過程中出現異常而終止.那麼下個任務將會建立一個新的執行緒. Executors.newCachedThreadPool(); 建立一個無邊界執行緒池.如

執行原理--工廠類Executors

文章目錄 執行緒池原理--工廠類Executors 構造器 newFixedThreadPool newSingleThreadExecutor newCachedThreadPool newScheduledThre

Executors提供的四種執行

Java 5+中的Executor介面定義一個執行執行緒的工具。它的子型別即執行緒池介面是ExecutorService。要配置一個執行緒池是比較複雜的,尤其是對於執行緒池的原理不是很清楚的情況下,因此在工具類Executors面提供了一些靜態工廠方法,生成一些常用的執行緒池,如下所示:  -&n

java併發程式設計--Executor框架以及Executors類的建立執行方法

       Eexecutor作為靈活且強大的非同步執行框架,其支援多種不同型別的任務執行策略,提供了一種標準的方法將任務的提交過程和執行過程解耦開發,基於生產者-消費者模式,其提交任務的執行緒相當於生產者,執行任務的執行緒相當於消費者,並用Runnab

【小家Java】一次Java執行誤用(newFixedThreadPool)引發的線上血案和總結

相關閱讀 【小家java】java5新特性(簡述十大新特性) 重要一躍 【小家java】java6新特性(簡述十大新特性) 雞肋升級 【小家java】java7新特性(簡述八大新特性) 不溫不火 【小家java】java8新特性(簡述十大新特性) 飽受讚譽 【小家java】java9

執行的建立與執行ThreadPoolExecutor,Executors

                    執行緒的建立與執行緒池及執行緒池工具類 1.執行緒的建立方式 1.1繼承Thread類重寫run方法 public class Test { p