1. 程式人生 > >java自帶執行緒池和佇列詳細講解

java自帶執行緒池和佇列詳細講解

Java執行緒池使用說明

簡介

執行緒的使用在java中佔有極其重要的地位,在jdk1.4極其之前的jdk版本中,關於執行緒池的使用是極其簡陋的。在jdk1.5之後這一情況有了很大的改觀。Jdk1.5之後加入了java.util.concurrent包,這個包中主要介紹java中執行緒以及執行緒池的使用。為我們在開發中處理執行緒的問題提供了非常大的幫助。

二:執行緒池

執行緒池的作用:

執行緒池作用就是限制系統中執行執行緒的數量。根據系統的環境情況,可以自動或手動設定執行緒數量,達到執行的最佳效果;少了浪費了系統資源,多了造成系統擁擠效率不高。用執行緒池控制執行緒數量,其他執行緒排隊等候。一個任務執行完畢,再從佇列的中取最前面的任務開始執行。若佇列中沒有等待程序,執行緒池的這一資源處於等待。當一個新任務需要執行時,如果執行緒池中有等待的工作執行緒,就可以開始運行了;否則進入等待佇列。

為什麼要用執行緒池:

1.減少了建立和銷燬執行緒的次數,每個工作執行緒都可以被重複利用,可執行多個任務。

2.可以根據系統的承受能力,調整執行緒池中工作線執行緒的數目,防止因為消耗過多的記憶體,而把伺服器累趴下(每個執行緒需要大約1MB記憶體,執行緒開的越多,消耗的記憶體也就越大,最後宕機)

Java裡面執行緒池的頂級介面是Executor,但是嚴格意義上講Executor並不是一個執行緒池,而只是一個執行執行緒的工具。真正的執行緒池介面是ExecutorService

比較重要的幾個類:

ExecutorService

真正的執行緒池介面。

ScheduledExecutorService

能和Timer/TimerTask類似,解決那些需要任務重複執行的問題。

ThreadPoolExecutor

ExecutorService的預設實現。

ScheduledThreadPoolExecutor

繼承ThreadPoolExecutorScheduledExecutorService介面實現,週期性任務排程的類實現。

要配置一個執行緒池是比較複雜的,尤其是對於執行緒池的原理不是很清楚的情況下,很有可能配置的執行緒池不是較優的,因此在Executors類裡面提供了一些靜態工廠,生成一些常用的執行緒池。

1. newSingleThreadExecutor

建立一個單執行緒的執行緒池。這個執行緒池只有一個執行緒在工作,也就是相當於單執行緒序列執行所有任務。如果這個唯一的執行緒因為異常結束,那麼會有一個新的執行緒來替代它。此執行緒池保證所有任務的執行順序按照任務的提交順序執行。

2.newFixedThreadPool

建立固定大小的執行緒池。每次提交一個任務就建立一個執行緒,直到執行緒達到執行緒池的最大大小。執行緒池的大小一旦達到最大值就會保持不變,如果某個執行緒因為執行異常而結束,那麼執行緒池會補充一個新執行緒。

3. newCachedThreadPool

建立一個可快取的執行緒池。如果執行緒池的大小超過了處理任務所需要的執行緒,

那麼就會回收部分空閒(60秒不執行任務)的執行緒,當任務數增加時,此執行緒池又可以智慧的新增新執行緒來處理任務。此執行緒池不會對執行緒池大小做限制,執行緒池大小完全依賴於作業系統(或者說JVM)能夠建立的最大執行緒大小。

4.newScheduledThreadPool

建立一個大小無限的執行緒池。此執行緒池支援定時以及週期性執行任務的需求。

例項

1newSingleThreadExecutor

MyThread.java

publicclassMyThread extends Thread {

@Override

publicvoid run() {

System.out.println(Thread.currentThread().getName() + "正在執行。。。");

}

}

TestSingleThreadExecutor.java

publicclassTestSingleThreadExecutor {

publicstaticvoid main(String[] args) {

//建立一個可重用固定執行緒數的執行緒池

ExecutorService pool = Executors. newSingleThreadExecutor();

//建立實現了Runnable介面物件,Thread物件當然也實現了Runnable介面

Thread t1 = new MyThread();

Thread t2 = new MyThread();

Thread t3 = new MyThread();

Thread t4 = new MyThread();

Thread t5 = new MyThread();

//將執行緒放入池中進行執行

pool.execute(t1);

pool.execute(t2);

pool.execute(t3);

pool.execute(t4);

pool.execute(t5);

//關閉執行緒池

pool.shutdown();

}

}

輸出結果

pool-1-thread-1正在執行。。。

pool-1-thread-1正在執行。。。

pool-1-thread-1正在執行。。。

pool-1-thread-1正在執行。。。

pool-1-thread-1正在執行。。。

2newFixedThreadPool

TestFixedThreadPool.Java

publicclass TestFixedThreadPool {

publicstaticvoid main(String[] args) {

//建立一個可重用固定執行緒數的執行緒池

ExecutorService pool = Executors.newFixedThreadPool(2);

//建立實現了Runnable介面物件,Thread物件當然也實現了Runnable介面

Thread t1 = new MyThread();

Thread t2 = new MyThread();

Thread t3 = new MyThread();

Thread t4 = new MyThread();

Thread t5 = new MyThread();

//將執行緒放入池中進行執行

pool.execute(t1);

pool.execute(t2);

pool.execute(t3);

pool.execute(t4);

pool.execute(t5);

//關閉執行緒池

pool.shutdown();

}

}

輸出結果

pool-1-thread-1正在執行。。。

pool-1-thread-2正在執行。。。

pool-1-thread-1正在執行。。。

pool-1-thread-2正在執行。。。

pool-1-thread-1正在執行。。。

3 newCachedThreadPool

TestCachedThreadPool.java

publicclass TestCachedThreadPool {

publicstaticvoid main(String[] args) {

//建立一個可重用固定執行緒數的執行緒池

ExecutorService pool = Executors.newCachedThreadPool();

//建立實現了Runnable介面物件,Thread物件當然也實現了Runnable介面

Thread t1 = new MyThread();

Thread t2 = new MyThread();

Thread t3 = new MyThread();

Thread t4 = new MyThread();

Thread t5 = new MyThread();

//將執行緒放入池中進行執行

pool.execute(t1);

pool.execute(t2);

pool.execute(t3);

pool.execute(t4);

pool.execute(t5);

//關閉執行緒池

pool.shutdown();

}

}

輸出結果:

pool-1-thread-2正在執行。。。

pool-1-thread-4正在執行。。。

pool-1-thread-3正在執行。。。

pool-1-thread-1正在執行。。。

pool-1-thread-5正在執行。。。

4newScheduledThreadPool

TestScheduledThreadPoolExecutor.java

publicclass TestScheduledThreadPoolExecutor {

publicstaticvoid main(String[] args) {

ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1);

exec.scheduleAtFixedRate(new Runnable() {//每隔一段時間就觸發異常

@Override

publicvoid run() {

//throw new RuntimeException();

System.out.println("================");

}

}, 1000, 5000, TimeUnit.MILLISECONDS);

exec.scheduleAtFixedRate(new Runnable() {//每隔一段時間列印系統時間,證明兩者是互不影響的

@Override

publicvoid run() {

System.out.println(System.nanoTime());

}

}, 1000, 2000, TimeUnit.MILLISECONDS);

}

}

輸出結果

================

8384644549516

8386643829034

8388643830710

================

8390643851383

8392643879319

8400643939383

三:ThreadPoolExecutor詳解

ThreadPoolExecutor的完整構造方法的簽名是:ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) .

corePoolSize - 池中所儲存的執行緒數,包括空閒執行緒。

maximumPoolSize-池中允許的最大執行緒數。

keepAliveTime - 當執行緒數大於核心時,此為終止前多餘的空閒執行緒等待新任務的最長時間。

unit - keepAliveTime 引數的時間單位。

workQueue - 執行前用於保持任務的佇列。此佇列僅保持由 execute方法提交的 Runnable任務。

threadFactory - 執行程式建立新執行緒時使用的工廠。

handler - 由於超出執行緒範圍和佇列容量而使執行被阻塞時所使用的處理程式。

ThreadPoolExecutorExecutors類的底層實現。

JDK幫助文件中,有如此一段話:

強烈建議程式設計師使用較為方便的Executors工廠方法Executors.newCachedThreadPool()(無界執行緒池,可以進行自動執行緒回收)、Executors.newFixedThreadPool(int)(固定大小執行緒池)Executors.newSingleThreadExecutor()(單個後臺執行緒)

它們均為大多數使用場景預定義了設定。

下面介紹一下幾個類的原始碼:

ExecutorServicenewFixedThreadPool (int nThreads):固定大小執行緒池。

可以看到,corePoolSizemaximumPoolSize的大小是一樣的(實際上,後面會介紹,如果使用無界queue的話maximumPoolSize引數是沒有意義的),keepAliveTimeunit的設值表名什麼?-就是該實現不想keep alive!最後的BlockingQueue選擇了LinkedBlockingQueuequeue有一個特點,他是無界的

1.public static ExecutorService newFixedThreadPool(int nThreads) {   

2.        return new ThreadPoolExecutor(nThreads, nThreads,   

3.                                      0L, TimeUnit.MILLISECONDS,   

4.                                      new LinkedBlockingQueue<Runnable>());   

5.    }

ExecutorServicenewSingleThreadExecutor():單執行緒

相關推薦

java執行佇列詳細講解

Java執行緒池使用說明 一簡介 執行緒的使用在java中佔有極其重要的地位,在jdk1.4極其之前的jdk版本中,關於執行緒池的使用是極其簡陋的。在jdk1.5之後這一情況有了很大的改觀。Jdk1.5之後加入了java.util.concurrent包,這個包中主要介紹j

java.jse-執行-執行-java執行佇列詳細講解

Java執行緒池使用說明 一簡介 執行緒的使用在java中佔有極其重要的地位,在jdk1.4極其之前的jdk版本中,關於執行緒池的使用是極其簡陋的。在jdk1.5之後這一情況有了很大的改觀。Jdk1.5之後加入了java.util.concurrent包,這個包中主要介紹

java concurrent包執行佇列詳細講解

Java執行緒池使用說明一簡介執行緒的使用在java中佔有極其重要的地位,在jdk1.4極其之前的jdk版本中,關於執行緒池的使用是極其簡陋的。在jdk1.5之後這一情況有了很大的改觀。Jdk1.5之後加入了java.util.concurrent包,這個包中主要介紹java

java執行佇列詳細講解

Java執行緒池使用說明 一簡介 執行緒的使用在java中佔有極其重要的地位,在jdk1.4極其之前的jdk版本中,關於執行緒池的使用是極其簡陋的。在jdk1.5之後這一情況有了很大的改觀。Jdk1.5之後加入了java.util.concurrent包,這個包中主要介紹j

使用java執行

  java提供自帶的執行緒池,而不需要自己去開發一個自定義執行緒池了。 執行緒池類 ThreadPoolExecutor在包java.util.concurrent下 &nb

Java定義執行執行總數控制

1 概述池化是常見的思想,執行緒池是非常典型的池化的實現,《Java併發程式設計實戰》也大篇幅去講解了Java中的執行緒池。本文實現一個簡單的執行緒池。 2 核心類 【1】介面定義 public interface IThreadPool<Job extends

Java執行技術之二 Java執行實現

一,介紹   類檢視如下:     自Java 1.5後,Java對執行緒相關的庫做了很大的拓展,執行緒池就是其中之一。Java執行緒的新特性多數在java.util.concurrent,其包含眾多的介面和類。其中java.util.concurrent.Execut

盤點java併發包提供的執行佇列

執行緒池 newCachedThreadPool() newFixedThreadPool(int nThreads) newSingleThreadPoolExecutor() newScheduledThreadPool(int corePoolSize

Java四種執行工作佇列

public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {

java執行佇列分析

Java專案 當想讓程式非同步操作的時候,首先考慮使用Java多執行緒,但有的時候我們總會在想是簡單的extends Thread 、implements Runnable介面還是使用執行緒池呢?而大多開發者可能更會選擇使用執行緒池,.減少了建立和銷燬執行緒的次數,每個工作

python執行

1.  注意:  導包是:     from multiprocessing.pool import ThreadPool  #執行緒池不在thrading中 2.  程式碼:   from mutiprocessing.pool import ThreadPool   def func(*args,

java定義執行--ThreadPoolExecutors

public class MyThreadPool { public static void main(String[] args) { /** * 1.在使用有界佇列的時候:若有新的任務需要執行,如果執行緒池實際執行緒數小於corePoolSize核心執行緒數的時候,則優先建立執行緒。

jdk執行詳解

一、前言 在最近做的一個專案中,需要大量的使用到多執行緒和執行緒池,下面就java自帶的執行緒池和大家一起分享。 二、簡介 多執行緒技術主要解決處理器單元內多個執行緒執行的問題,它可以顯著減少處理器單元的閒置時間,增加處理器單元的吞吐能力,但頻繁的建立執行緒的開銷是很大的,

Java併發程式設計:4種執行緩衝佇列BlockingQueue

一. 執行緒池簡介 1. 執行緒池的概念:           執行緒池就是首先建立一些執行緒,它們的集合稱為執行緒池。使用執行緒池可以很好地提高效能,執行緒池在系統啟動時即建立大量空閒的執行緒,程式將一個任務傳給執行緒池,執行緒池就會啟動一

JAVA執行(三) 執行鎖的深度化

 github演示程式碼地址:https://github.com/showkawa/springBoot_2017/tree/master/spb-demo/src/main/java/com/kawa/thread 1.執行緒池  1.1 執行緒池是什麼 Java中的執行緒

2.3四種執行連線的配置使用(定義執行

四種執行緒連線池的配置和使用 最終呼叫類和方法 {引數有 核心執行緒數目,最大執行緒數目,存活時間(當前執行緒執行完這個任務之後,等待下一個任務到來的最長等待時間。如果在這個時間內沒有新的任務來到,那當前執行緒就會退出),時間單位,等待佇列(用於存放待執行的任務)} public

java執行資料庫連線[從學習到工作(二)]

背景:前段時間工作需要開發一個socket服務端,在接受到客戶端發過來的報文資訊後解析報文呼叫資料庫程式完成資料檔案的生成再拼湊結果報文反饋給客戶端。由於客戶數比較多,所以用執行緒池和資料庫連線池。        一.執行緒池   

18.Java語言執行Lambda表示式

執行緒等待喚醒機制 1.執行緒間的通訊:        一個程式完成某個任務,需要多個執行緒協調,就需要執行緒之間存在“通訊”,比如生產者和消費者,只有生產了才能被消費。當生產者生產完成才能告知消費者可以消費,那麼告知的過程就是執行緒間的通訊。 2.等待與喚醒機制:

OKHttp 3.10原始碼解析(一):執行任務佇列

OKhttp是Android端最火熱的網路請求框架之一,它以高效的優點贏得了廣大開發者的喜愛,下面是OKhttp的主要特點: 1.支援HTTPS/HTTP2/WebSocket 2.內部維護執行緒池佇列,提高併發訪問的效率 3.內部維護連線池,支援多路複用,減少連線建立開銷 4.

初識Java中的四大執行ThreadPoolExecutor的使用(歡迎指正)

初識Java中的四大執行緒池和ThreadPoolExecutor的使用(轉載+自身心得) 為什麼用執行緒池? 1.建立/銷燬執行緒伴隨著系統開銷,過於頻繁的建立/銷燬執行緒,會很大程度上影響處-理效率; 2.執行緒併發數量過多,搶佔系統資源從而導致阻塞; 3.對執行緒進行一些簡單的