1. 程式人生 > >Java四種執行緒池的弊端,和如何自己通過ThreadPoolExecutor的方式建立執行緒池

Java四種執行緒池的弊端,和如何自己通過ThreadPoolExecutor的方式建立執行緒池

【強制】執行緒池不允許使用 Executors 去建立,而是通過 ThreadPoolExecutor 的方式,

這樣的處理方式讓寫的同學更加明確執行緒池的執行規則,規避資源耗盡的風險。

下面我們說說通過Executors建立的四種執行緒池的弊端:因為使用Executors建立執行緒池不會傳入拒絕策略這個引數而使用預設值所以我們常常忽略這一引數.

讓我們再看看Executors提供的那幾個工廠方法。

newSingleThreadExecutor

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

new ThreadPoolExecutor(1, 1,0L,TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>())

newFixedThreadPool

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

new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());

newCachedThreadPool

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

new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS,new SynchronousQueue<Runnable>());
下面我們來看看如何通過ThreadPoolExcutor自己手動去建立執行緒池:

ThreadPoolExecutor

先看看如何使用ThreadPoolExecutor建立執行緒池:

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

corePoolSize - 執行緒池核心池的大小。
maximumPoolSize - 執行緒池的最大執行緒數。
keepAliveTime - 當執行緒數大於核心時,此為終止前多餘的空閒執行緒等待新任務的最長時間。
unit - keepAliveTime 的時間單位。
workQueue - 用來儲存等待執行任務的佇列。
threadFactory - 執行緒工廠。
handler - 拒絕策略。

關注點1 執行緒池大小

執行緒池有兩個執行緒數的設定,一個為核心池執行緒數,一個為最大執行緒數。
在建立了執行緒池後,預設情況下,執行緒池中並沒有任何執行緒,等到有任務來才建立執行緒去執行任務,除非呼叫了prestartAllCoreThreads()或者prestartCoreThread()方法
當建立的執行緒數等於 corePoolSize 時,會加入設定的阻塞佇列。當佇列滿時,會建立執行緒執行任務直到執行緒池中的數量等於maximumPoolSize。

關注點2 適當的阻塞佇列

java.lang.IllegalStateException: Queue full
方法 丟擲異常 返回特殊值 一直阻塞 超時退出
插入方法 add(e) offer(e) put(e) offer(e,time,unit)
移除方法 remove() poll() take() poll(time,unit)
檢查方法 element() peek() 不可用 不可用

ArrayBlockingQueue :一個由陣列結構組成的有界阻塞佇列。
LinkedBlockingQueue :一個由連結串列結構組成的有界阻塞佇列。
PriorityBlockingQueue :一個支援優先順序排序的無界阻塞佇列。
DelayQueue: 一個使用優先順序佇列實現的無界阻塞佇列。
SynchronousQueue: 一個不儲存元素的阻塞佇列。
LinkedTransferQueue: 一個由連結串列結構組成的無界阻塞佇列。
LinkedBlockingDeque: 一個由連結串列結構組成的雙向阻塞佇列。

關注點3 明確拒絕策略

ThreadPoolExecutor.AbortPolicy: 丟棄任務並丟擲RejectedExecutionException異常。 (預設)
ThreadPoolExecutor.DiscardPolicy:也是丟棄任務,但是不丟擲異常。
ThreadPoolExecutor.DiscardOldestPolicy:丟棄佇列最前面的任務,然後重新嘗試執行任務(重複此過程)
ThreadPoolExecutor.CallerRunsPolicy:由呼叫執行緒處理該任務

說明:Executors 各個方法的弊端:
1)newFixedThreadPool 和 newSingleThreadExecutor:
主要問題是堆積的請求處理佇列可能會耗費非常大的記憶體,甚至 OOM。
2)newCachedThreadPool 和 newScheduledThreadPool:
主要問題是執行緒數最大數是 Integer.MAX_VALUE,可能會建立數量非常多的執行緒,甚至 OOM。


參考文件:http://www.cnblogs.com/dolphin0520/p/3932921.html

相關推薦

不推薦使用Executors建立執行,推薦通過ThreadPoolExecutor方式建立

執行緒池不允許使用Executors去建立,而是通過ThreadPoolExecutor的方式,這樣的處理方式讓寫的同學更加明確執行緒池的執行規則,規避資源耗盡的風險。 說明:Executors各個方法的弊端: 1)newFixedThreadPool和newSingleThreadExecut

Java執行弊端,如何自己通過ThreadPoolExecutor方式建立執行

【強制】執行緒池不允許使用 Executors 去建立,而是通過 ThreadPoolExecutor 的方式,這樣的處理方式讓寫的同學更加明確執行緒池的執行規則,規避資源耗盡的風險。 下面我們說說通過Executors建立的四種執行緒池的弊端:因為使用Executors建

介紹new Thread的弊端Java執行的使用

介紹new Thread的弊端及Java四種執行緒池的使用,對Android同樣適用。本文是基礎篇,後面會分享下執行緒池一些高階功能。 1、new Thread的弊端 執行一個非同步任務你還只是如下new Thread嗎? Java

new Thread的弊端Java執行的使用

介紹new Thread的弊端及Java四種執行緒池的使用,對Android同樣適用。本文是基礎篇,後面會分享下執行緒池一些高階功能。 1、new Thread的弊端 執行一個非同步任務你還只是如下new Thread嗎? Java

理解new Thread的弊端Java執行的使用

1.new Thread的弊端 執行一個非同步任務你還只是如下new Thread嗎? new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated

Java執行工作佇列

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

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 執行 - 使用

轉:https://www.cnblogs.com/zhujiabin/p/5404771.html 介紹new Thread的弊端及Java四種執行緒池的使用,對Android同樣適用。本文是基礎篇,後面會分享下執行緒池一些高階功能。 1、new Thread的弊端 執行一個非同步任務你還

Java執行使用

Java 四種執行緒池的使用 https://juejin.im/post/59df0c1af265da432f301c8d 1,執行緒池的作用 執行緒池作用就是限制系統中執行執行緒的數量。 根據系統的環境情況,可以自動或手動設定執行緒數量,達到執行的最佳效果。 少

Java 常見執行解析

四種常見執行緒池   執行緒池用於管理執行緒的建立與銷燬,避免無用執行緒造成資源浪費,當需要建立多個執行緒時,我們往往需要一個管理者來管理這些執行緒,這也就引入了執行緒池的概念.Android中有四種較為常見的執行緒池也是我們使用最廣泛的執行緒池,Fixed

Java 執行

介紹new Thread的弊端及Java四種執行緒池的使用,對Android同樣適用。本文是基礎篇,後面會分享下執行緒池一些高階功能。 1、new Thread的弊端 執行一個非同步任務你還只是如下new Thread嗎? new Thread(new Runna

Java執行介紹

Java四種執行緒池 java.util.concurrent.Executors工廠類可以建立四種類型的執行緒池,通過Executors.newXXX方法即可建立。 public ThreadPoolExecutor(int corePoolSize,

java執行詳解與使用

1、什麼是執行緒池 在解釋什麼是執行緒池前,再贅述下什麼是執行緒: 1、執行緒:現代作業系統在執行一個程式時, 會為其建立一個程序。 例如, 啟動一個Java程式, 作業系統就會建立一個Java進 程。 現代作業系統排程的最小單元是執行緒, 也叫輕量級程序(Light

JAVA執行詳解

執行緒池採取上述的流程進行設計是為了減少獲取全域性鎖的次數。線上程池完成預熱(當前執行的執行緒數大於或等於corePoolSize)之後,幾乎所有的excute方法呼叫都執行步驟2。 執行緒池的作用: 1. 執行緒池作用就是限制系統中執行執行緒的數量。 2. 根據系統的環境情況,可以自動或手動設定執行緒數量

Java執行使用方法

1.new Thread的弊端執行一個非同步任務你還只是如下new Thread嗎?1234567new Thread(new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stub

Java執行的使用

http://cuisuqiang.iteye.com/blog/2019372 http://www.cnblogs.com/riskyer/p/3263032.html http://blog.csdn.net/mazhimazh/article/details/192

java 執行的簡介

前瞻 四種執行緒池內部構造都是來自同一個方法: 下面分別介紹一下各個引數的含義: corePoolSize: 執行緒池中所儲存的核心執行緒數。執行緒池初始化啟動之後,預設是空的,只有當任務來臨之時,才會建立執行緒 處理請求。當然可以使

Java執行的使用以及callable future整理

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

java執行的使用

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

java線程簡介,使用

參數 有一個 例子 system pre mit time style over 為什麽使用線程池 1.減少了創建和銷毀線程的次數,每個工作線程都可以被重復利用,可執行多個任務。2.可以根據系統的承受能力,調整線程池中工作線線程的數目,防止消耗過多的內存 線程池流程