真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Java并發(fā)編程中線程池工作原理的示例分析

Java并發(fā)編程中線程池工作原理的示例分析,相信很多沒有經(jīng)驗(yàn)的人對(duì)此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個(gè)問題。

創(chuàng)新互聯(lián)建站公司2013年成立,先為衡陽(yáng)縣等服務(wù)建站,衡陽(yáng)縣等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為衡陽(yáng)縣企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。

線程池繼承關(guān)系

Java并發(fā)編程中線程池工作原理的示例分析

ThreadPoolExecutor實(shí)現(xiàn)的頂層接口是Executor,在接口Executor中用戶無需關(guān)注如何創(chuàng)建線程,如何調(diào)度線程來執(zhí)行任務(wù),用戶只需提供Runnable對(duì)象,將任務(wù)的運(yùn)行邏輯提交到執(zhí)行器Executor中,由Executor框架完成線程的調(diào)配和任務(wù)的執(zhí)行部分。

ExecutorService接口增加了一些能力

  • 擴(kuò)充執(zhí)行任務(wù)的能力,補(bǔ)充可以為一個(gè)或一批異步任務(wù)生成Future的方法;

  • 提供了管控線程池的方法,比如停止線程池的運(yùn)行。

AbstractExecutorService則是上層的抽象類

將執(zhí)行任務(wù)的流程串聯(lián)了起來,保證下層的實(shí)現(xiàn)只需關(guān)注一個(gè)執(zhí)行任務(wù)的方法即可。

ThreadPoolExecutor實(shí)現(xiàn)最復(fù)雜的運(yùn)行部分:

可以自動(dòng)創(chuàng)建、管理和復(fù)用指定數(shù)量的一組線程,適用方只需提交任務(wù)即可線程安全,ThreadPoolExecutor內(nèi)部有狀態(tài)、核心線程數(shù)、非核心線程等屬性,廣泛使用了CAS和AQS鎖機(jī)制避免并發(fā)帶來的沖突問題

提供了核心線程、緩沖阻塞隊(duì)列、非核心線程、拋棄策略的概念,可以根據(jù)實(shí)際應(yīng)用場(chǎng)景進(jìn)行組合使用

提供了beforeExecute 和afterExecute()可以支持對(duì)線程池的功能進(jìn)行擴(kuò)展

線程池的優(yōu)點(diǎn)

降低線程創(chuàng)建和銷毀線程造成的開銷

  • 提高響應(yīng)速度:任務(wù)到達(dá)時(shí),相對(duì)于手工創(chuàng)建一個(gè)線程,直接從線程池中拿線程,速度肯定快很多

  • 提高線程可管理性:線程是稀缺資源,如果無限制地創(chuàng)建,不僅會(huì)消耗系統(tǒng)資源,還會(huì)降低系統(tǒng)穩(wěn)定性,使用線程池可以進(jìn)行同意分配、調(diào)優(yōu)和監(jiān)控。

構(gòu)造函數(shù)

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler) {
    if (corePoolSize < 0 ||
        maximumPoolSize <= 0 ||
        maximumPoolSize < corePoolSize ||
        keepAliveTime < 0)
        throw new IllegalArgumentException();
    if (workQueue == null || threadFactory == null || handler == null)
        throw new NullPointerException();
    this.acc = System.getSecurityManager() == null ?
            null :
            AccessController.getContext();
    this.corePoolSize = corePoolSize;
    this.maximumPoolSize = maximumPoolSize;
    this.workQueue = workQueue;
    this.keepAliveTime = unit.toNanos(keepAliveTime);
    this.threadFactory = threadFactory;
    this.handler = handler;
}

  • corePoolSize:線程池的核心線程數(shù),一般情況下不管有沒有任務(wù)都會(huì)一直在線程池中一直存活,只有在 ThreadPoolExecutor中的方法allowCoreThreadTimeOut(boolean value)設(shè)置為true時(shí),閑置的核心線程會(huì)存在超時(shí)機(jī)制,如果在指定時(shí)間沒有新任務(wù)來時(shí),核心線程也會(huì)被終止,而這個(gè)時(shí)間間隔由第3個(gè)屬性keepAliveTime指定。

  • maximumPoolSize:線程池所能容納的最大線程數(shù),當(dāng)活動(dòng)的線程數(shù)達(dá)到這個(gè)值后,后續(xù)的新任務(wù)將會(huì)被阻塞。

  • keepAliveTime:控制線程閑置時(shí)的超時(shí)時(shí)長(zhǎng),超過則終止該線程。一般情況下用于非核心線程,只有在 ThreadPoolExecutor中的方法allowCoreThreadTimeOut(boolean value)設(shè)置為true時(shí),也作用于核心線程。

  • unit:用于指定keepAliveTime參數(shù)的時(shí)間單位,TimeUnit是個(gè)enum枚舉類型,常用的有:TimeUnit.HOURS(小時(shí))、TimeUnit.MINUTES(分鐘)、TimeUnit.SECONDS(秒) 和 TimeUnit.MILLISECONDS(毫秒)等。

  • workQueue:線程池的任務(wù)隊(duì)列,通過線程池的execute(Runnable command)方法會(huì)將任務(wù)Runnable存儲(chǔ)在隊(duì)列中。

  • threadFactory:線程工廠,它是一個(gè)接口,用來為線程池創(chuàng)建新線程的。

  • handler:拒絕策略,所謂拒絕策略,是指將任務(wù)添加到線程池中時(shí),線程池拒絕該任務(wù)所采取的相應(yīng)策略。


成員變量

/**
 * 任務(wù)阻塞隊(duì)列 
 */
private final BlockingQueue workQueue; 
/**
 * 非公平的互斥鎖(可重入鎖)
 */
private final ReentrantLock mainLock = new ReentrantLock();
/**
 * 線程集合一個(gè)Worker對(duì)應(yīng)一個(gè)線程,沒有核心線程的說話,只有核心線程數(shù)
 */
private final HashSet workers = new HashSet();
/**
 * 配合mainLock通過Condition能夠更加精細(xì)的控制多線程的休眠與喚醒
 */
private final Condition termination = mainLock.newCondition();
/**
 * 線程池中線程數(shù)量曾經(jīng)達(dá)到過的最大值。
 */
private int largestPoolSize;  
/**
 * 已完成任務(wù)數(shù)量
 */
private long completedTaskCount;
/**
 * ThreadFactory對(duì)象,用于創(chuàng)建線程。
 */
private volatile ThreadFactory threadFactory;  
/**
 * 拒絕策略的處理句柄
 * 現(xiàn)在默認(rèn)提供了CallerRunsPolicy、AbortPolicy、DiscardOldestPolicy、DiscardPolicy
 */
private volatile RejectedExecutionHandler handler;
/**
 * 線程池維護(hù)線程(超過核心線程數(shù))所允許的空閑時(shí)間
 */
private volatile long keepAliveTime;
/**
 * 允許線程池中的核心線程超時(shí)進(jìn)行銷毀
 */
private volatile boolean allowCoreThreadTimeOut;  
/**
 * 線程池維護(hù)線程的最小數(shù)量,哪怕是空閑的  
 */
private volatile int corePoolSize;
/**
 * 線程池維護(hù)的最大線程數(shù)量,線程數(shù)超過這個(gè)數(shù)量之后新提交的任務(wù)就需要進(jìn)入阻塞隊(duì)列
 */
private volatile int maximumPoolSize;

創(chuàng)建線程池

緩存程線程池(不會(huì)存放隊(duì)列,一直創(chuàng)建線程)

核心線程數(shù)為0,總線程數(shù)量閾值為Integer.MAX_VALUE,即可以創(chuàng)建無限的非核心線程

newCachedThreadPool是一個(gè)可根據(jù)需要?jiǎng)?chuàng)建新線程的線程池,但是在以前構(gòu)造的線程可用時(shí)將重用它們。對(duì)于執(zhí)行很多短期異步任務(wù)的程序而言,這些線程池通??商岣叱绦蛐阅堋U{(diào)用 execute() 將重用以前構(gòu)造的線程(如果線程可用)。如果現(xiàn)有線程沒有可用的,則創(chuàng)建一個(gè)新線程并添加到池中。終止并從緩存中移除那些已有 60秒鐘未被使用的線程。因此,長(zhǎng)時(shí)間保持空閑的線程池不會(huì)使用任何資源。注意,可以使用 ThreadPoolExecutor構(gòu)造方法創(chuàng)建具有類似屬性但細(xì)節(jié)不同(例如超時(shí)參數(shù))的線程池。

會(huì)出下面大量的線程對(duì)象,導(dǎo)致的OOM

public static ExecutorService newCachedThreadPool() {
  return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                  60L, TimeUnit.SECONDS,
                  new SynchronousQueue());
}

執(zhí)行流程

  • 先執(zhí)行SynchronousQueue的offer方法提交任務(wù),并查詢線程池中是否有空閑線程來執(zhí)行SynchronousQueue的poll方法來移除任務(wù)。如果有,則配對(duì)成功,將任務(wù)交給這個(gè)空閑線程,否則,配對(duì)失敗,創(chuàng)建新的線程去處理任務(wù)

  • 當(dāng)線程池中的線程空閑時(shí),會(huì)執(zhí)行SynchronousQueue的poll方法等待執(zhí)行SynchronousQueue中新提交的任務(wù)。若等待超過60s,空閑線程就會(huì)終止

Java并發(fā)編程中線程池工作原理的示例分析


Java并發(fā)編程中線程池工作原理的示例分析

使用場(chǎng)景

執(zhí)行大量短生命周期任務(wù)。因?yàn)閙aximumPoolSize是無界的,所以提交任務(wù)的速度 > 線程池中線程處理任務(wù)的速度就要不斷創(chuàng)建新線程;每次提交任務(wù),都會(huì)立即有線程去處理,因此CachedThreadPool適用于處理大量、耗時(shí)少的任務(wù)。


單線程線程池(只會(huì)運(yùn)行一個(gè)線程,否則一直會(huì)堆積到阻塞隊(duì)列)

它適用于需要保證順序地執(zhí)行各個(gè)任務(wù);并且在任意時(shí)間點(diǎn),不會(huì)有多個(gè)線程是活動(dòng)的應(yīng)用場(chǎng)景,SingleThreadExecutor的corePoolSize和maximumPoolSize被設(shè)置為1,使用無界隊(duì)列LinkedBlockingQueue作為線程池的工作隊(duì)列

newSingleThreadExecutor創(chuàng)建是一個(gè)單線程池,也就是該線程池只有一個(gè)線程在工作,所有的任務(wù)是串行執(zhí)行的,如果這個(gè)唯一的線程因?yàn)楫惓=Y(jié)束,那么會(huì)有一個(gè)新的線程來替代它,此線程池保證所有任務(wù)的執(zhí)行順序按照任務(wù)的提交順序執(zhí)行。

  • 當(dāng)線程池中沒有線程時(shí),會(huì)創(chuàng)建一個(gè)新線程來執(zhí)行任務(wù)。

  • 當(dāng)前線程池中有一個(gè)線程后,將新任務(wù)加入LinkedBlockingQueue

  • 線程執(zhí)行完第一個(gè)任務(wù)后,會(huì)在一個(gè)無限循環(huán)中反復(fù)從LinkedBlockingQueue獲取任務(wù)來執(zhí)行 。

使用場(chǎng)景:

**適用于串行執(zhí)行任務(wù)場(chǎng)景**

會(huì)存在出現(xiàn)阻塞隊(duì)列堆積過大,導(dǎo)致的OOM

public static ExecutorService newSingleThreadExecutor() {
  return new FinalizableDelegatedExecutorService
    (new ThreadPoolExecutor(1, 1,
                0L, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue()));
}

固定大小線程池(會(huì)運(yùn)行指定數(shù)量的線程,否則一直會(huì)堆積到阻塞隊(duì)列)

 corePoolSize等于maximumPoolSize,所以線程池中只有核心線程,使用無界阻塞隊(duì)列LinkedBlockingQueue作為工作隊(duì)列

使用場(chǎng)景

適用于處理CPU密集型的任務(wù),確保CPU在長(zhǎng)期被工作線程使用的情況下,盡可能的少的分配線程,即適用執(zhí)行長(zhǎng)期的任務(wù)。


newFixedThreadPool創(chuàng)建固定大小的線程池每次提交一個(gè)任務(wù)就創(chuàng)建一個(gè)線程,直到線程達(dá)到線程池的最大大小,線程池的大小一旦達(dá)到最大值就會(huì)保持不變,如果某個(gè)線程因?yàn)閳?zhí)行異常而結(jié)束,那么線程池會(huì)補(bǔ)充一個(gè)新線程。當(dāng)線程處于空閑狀態(tài)時(shí),他們并不會(huì)被回收,除非線程池被關(guān)閉。當(dāng)所有的線程都處于活動(dòng)狀態(tài)時(shí),新的任務(wù)都會(huì)處于等待狀態(tài),直到有線程空閑出來。

會(huì)存在出現(xiàn)阻塞隊(duì)列堆積大,導(dǎo)致的OOM

public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
  return new ThreadPoolExecutor(nThreads, nThreads,
                  0L, TimeUnit.MILLISECONDS,
                  new LinkedBlockingQueue(),
                  threadFactory);
}

定時(shí)任務(wù)線程池(任務(wù)隊(duì)列與最大值均為無限大小,一直堆積到阻塞隊(duì)列)

newScheduledThreadPool創(chuàng)建一個(gè)大小無限的線程池,此線程池支持定時(shí)以及周期性執(zhí)行任務(wù)的需求。

線程總數(shù)閾值為Integer.MAX_VALUE,工作隊(duì)列使用DelayedWorkQueue,非核心線程存活時(shí)間為0,所以線程池僅僅包含固定數(shù)目的核心線程。

會(huì)存在出現(xiàn)阻塞隊(duì)列堆積過大,導(dǎo)致的OOM

public static ScheduledExecutorService newScheduledThreadPool(
    int corePoolSize, ThreadFactory threadFactory) {
  return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
}
public ScheduledThreadPoolExecutor(int corePoolSize,
                   ThreadFactory threadFactory) {
  super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
      new DelayedWorkQueue(), threadFactory);
}

可以看出來上面的方法一共使用了DelayedWorkQueueLinkedBlockingQueueSynchronousQueue。這個(gè)就是線程核心之一的阻塞隊(duì)列。

兩種方式提交任務(wù):

  • scheduleAtFixedRate: 按照固定速率周期執(zhí)行

  • scheduleWithFixedDelay:上個(gè)任務(wù)延遲固定時(shí)間后執(zhí)行

任務(wù)阻塞隊(duì)列

它一般分為直接提交隊(duì)列、有界任務(wù)隊(duì)列、無界任務(wù)隊(duì)列、優(yōu)先任務(wù)隊(duì)列;

SynchronousQueue

直接提交隊(duì)列:設(shè)置為SynchronousQueue隊(duì)列,SynchronousQueue是一個(gè)特殊的BlockingQueue,它沒有容量,每執(zhí)行一個(gè)插入操作就會(huì)阻塞,需要再執(zhí)行一個(gè)刪除操作才會(huì)被喚醒,反之每一個(gè)刪除操作也都要等待對(duì)應(yīng)的插入操作。

一個(gè)不存儲(chǔ)元素的阻塞隊(duì)列,每個(gè)插入操作,必須等到另一個(gè)線程調(diào)用移除操作,否則插入操作一直處于阻塞狀態(tài)


SynchronousQueue隊(duì)列,提交的任務(wù)不會(huì)被保存,總是會(huì)馬上提交執(zhí)行。如果用于執(zhí)行任務(wù)的線程數(shù)量小于maximumPoolSize,則嘗試創(chuàng)建新的進(jìn)程,如果達(dá)到maximumPoolSize設(shè)置的最大值,則根據(jù)你設(shè)置的handler執(zhí)行拒絕策略。因此這種方式你提交的任務(wù)不會(huì)被緩存起來,而是會(huì)被馬上執(zhí)行,在這種情況下,你需要對(duì)你程序的并發(fā)量有個(gè)準(zhǔn)確的評(píng)估,才能設(shè)置合適的maximumPoolSize數(shù)量,否則很容易就會(huì)執(zhí)行拒絕策略;


ArrayBlockingQueue

有界的任務(wù)隊(duì)列:有界的任務(wù)隊(duì)列可以使用ArrayBlockingQueue實(shí)現(xiàn),如下所示:
new ThreadPoolExecutor(1, 2, 1000, TimeUnit.MILLISECONDS, new ArrayBlockingQueue(10),Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());

使用ArrayBlockingQueue有界任務(wù)隊(duì)列,若有新的任務(wù)需要執(zhí)行時(shí),線程池會(huì)創(chuàng)建新的線程,直到創(chuàng)建的線程數(shù)量達(dá)到corePoolSize時(shí),則會(huì)將新的任務(wù)加入到等待隊(duì)列中。若等待隊(duì)列已滿,即超過ArrayBlockingQueue初始化的容量,則繼續(xù)創(chuàng)建線程,直到線程數(shù)量達(dá)到maximumPoolSize設(shè)置的最大線程數(shù)量,若大于maximumPoolSize,則執(zhí)行拒絕策略。


在這種情況下,線程數(shù)量的上限與有界任務(wù)隊(duì)列的狀態(tài)有直接關(guān)系,如果有界隊(duì)列初始容量較大或者沒有達(dá)到超負(fù)荷的狀態(tài),線程數(shù)將一直維持在corePoolSize以下,反之當(dāng)任務(wù)隊(duì)列已滿時(shí),則會(huì)以maximumPoolSize為最大線程數(shù)上限。

LinkedBlockingQueue

無界的任務(wù)隊(duì)列:無界任務(wù)隊(duì)列可以使用LinkedBlockingQueue實(shí)現(xiàn),如下所示:
 new ThreadPoolExecutor(1, 2, 1000, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(),Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());

使用無界任務(wù)隊(duì)列,線程池的任務(wù)隊(duì)列可以無限制的添加新的任務(wù),而線程池創(chuàng)建的最大線程數(shù)量就是你corePoolSize設(shè)置的數(shù)量,也就是說在這種情況下maximumPoolSize這個(gè)參數(shù)是無效的,哪怕你的任務(wù)隊(duì)列中緩存了很多未執(zhí)行的任務(wù),當(dāng)線程池的線程數(shù)達(dá)到corePoolSize后,就不會(huì)再增加了;若后續(xù)有新的任務(wù)加入,則直接進(jìn)入隊(duì)列等待,當(dāng)使用這種任務(wù)隊(duì)列模式時(shí),一定要注意你任務(wù)提交與處理之間的協(xié)調(diào)與控制,不然會(huì)出現(xiàn)隊(duì)列中的任務(wù)由于無法及時(shí)處理導(dǎo)致一直增長(zhǎng),直到最后資源耗盡的問題。 Java并發(fā)編程中線程池工作原理的示例分析


Java并發(fā)編程中線程池工作原理的示例分析

PriorityBlockingQueue

優(yōu)先任務(wù)隊(duì)列:優(yōu)先任務(wù)隊(duì)列通過PriorityBlockingQueue實(shí)現(xiàn),使用平衡二叉樹堆,實(shí)現(xiàn)的具有優(yōu)先級(jí)的無界阻塞隊(duì)列

任務(wù)會(huì)按優(yōu)先級(jí)重新排列執(zhí)行,且線程池的線程數(shù)一直為corePoolSize,也就是只有一個(gè)。

PriorityBlockingQueue其實(shí)是一個(gè)特殊的無界隊(duì)列,它其中無論添加了多少個(gè)任務(wù),線程池創(chuàng)建的線程數(shù)也不會(huì)超過corePoolSize的數(shù)量,只不過其他隊(duì)列一般是按照先進(jìn)先出的規(guī)則處理任務(wù),而PriorityBlockingQueue隊(duì)列可以自定義規(guī)則根據(jù)任務(wù)的優(yōu)先級(jí)順序先后執(zhí)行。

其實(shí)LinkedBlockingQueue也是可以設(shè)置界限的,它默認(rèn)的界限是Integer.MAX_VALUE。同時(shí)也支持也支持構(gòu)造的時(shí)候設(shè)置隊(duì)列大小。

DelayQueue

無界阻塞延遲隊(duì)列,隊(duì)列中每個(gè)元素均有過期時(shí)間,當(dāng)從隊(duì)列獲取元素時(shí),只有過期元素才會(huì)出隊(duì)列。隊(duì)列頭元素是最塊要過期的元素。

拒絕策略

public interface RejectedExecutionHandler {
    void rejectedExecution(Runnable r, ThreadPoolExecutor executor);
}

當(dāng)Executor已經(jīng)關(guān)閉,即執(zhí)行了executorService.shutdown()方法后,或者Executor將有限邊界用于最大線程和工作隊(duì)列容量,且已經(jīng)飽和時(shí)。使用方法execute()提交的新任務(wù)將被拒絕. 在以上述情況下,execute方法將調(diào)用其RejectedExecutionHandler的rejectExecution()方法

RejectedExecutionHandler.rejectedExecution(java.lang.Runnable, java.util.concurrent.ThreadPoolExecutor)

AbortPolicy(默認(rèn)的拒絕策略)

也稱為終止策略,遭到拒絕將拋出運(yùn)行時(shí)RejectedExecutionException。業(yè)務(wù)方能通過捕獲異常及時(shí)得到對(duì)本次任務(wù)提交的結(jié)果反饋。

public static class AbortPolicy implements RejectedExecutionHandler {
  public AbortPolicy() { }
  public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
    throw new RejectedExecutionException("Task " + r.toString() +
                                         " rejected from " +
                                         e.toString());
  }
}

CallerRunsPolicy

擁有自主反饋控制,讓提交者執(zhí)行提交任務(wù),能夠減緩新任務(wù)的提交速度。這種情況是需要讓所有的任務(wù)都執(zhí)行完畢。

public static class CallerRunsPolicy implements RejectedExecutionHandler {
    public CallerRunsPolicy() { }
    public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
        if (!e.isShutdown()) {
            r.run();
        }
    }
}

DiscardPolicy

拒絕任務(wù)的處理程序,靜默丟棄任務(wù)。使用此策略,我們可能無法感知系統(tǒng)的異常狀態(tài)。慎用~!

public static class DiscardPolicy implements RejectedExecutionHandler {
    public DiscardPolicy() { }
    public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
    }
}

DiscardOldestPolicy

丟棄隊(duì)列中最前面的任務(wù),然后重新提交被拒絕的任務(wù)。是否要使用此策略需要看業(yè)務(wù)是否需要新老的替換,慎用~!(LRU)

public static class DiscardOldestPolicy implements RejectedExecutionHandler {
    public DiscardOldestPolicy() { }
    public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
        if (!e.isShutdown()) {
            e.getQueue().poll();
            e.execute(r);
        }
    }
}

運(yùn)作執(zhí)行流程

  1. 判斷線程池中核心線程數(shù)是否已達(dá)閾值corePoolSize,若否,則創(chuàng)建一個(gè)新核心線程執(zhí)行任務(wù)

  2. 若核心線程數(shù)已達(dá)閾值corePoolSize,判斷阻塞隊(duì)列workQueue是否已滿,若未滿,則將新任務(wù)添加進(jìn)阻塞隊(duì)列

  3. 若滿,再判斷,線程池中線程數(shù)是否達(dá)到閾值maximumPoolSize,若否,則新建一個(gè)非核心線程執(zhí)行任務(wù)。若達(dá)到閾值,則執(zhí)行線程池飽和策略。

線程池飽和策略分為一下幾種:

  • AbortPolicy:直接拋出一個(gè)異常,默認(rèn)策略

  • DiscardPolicy: 直接丟棄任務(wù)

  • DiscardOldestPolicy:拋棄下一個(gè)將要被執(zhí)行的任務(wù)(最舊任務(wù))

  • CallerRunsPolicy:主線程中執(zhí)行任務(wù)


Java并發(fā)編程中線程池工作原理的示例分析

合理配置線程池大小

 要想合理的配置線程池,就必須首先分析任務(wù)特性,可以從以下幾個(gè)角度來進(jìn)行分析:

  • 任務(wù)的性質(zhì):CPU密集型任務(wù),IO密集型任務(wù)和混合型任務(wù)。

  • 任務(wù)的優(yōu)先級(jí):高,中和低。

  • 任務(wù)的執(zhí)行時(shí)間:長(zhǎng),中和短。

  • 任務(wù)的依賴性:是否依賴其他系統(tǒng)資源,如數(shù)據(jù)庫(kù)連接。


根據(jù)任務(wù)所需要的cpu和io資源的量可以分為,
  • CPU密集型任務(wù):  主要是執(zhí)行計(jì)算任務(wù),響應(yīng)時(shí)間很快,cpu一直在運(yùn)行,這種任務(wù)cpu的利用率很高。

  • IO密集型任務(wù):主要是進(jìn)行IO操作,執(zhí)行IO操作的時(shí)間較長(zhǎng),這是cpu出于空閑狀態(tài),導(dǎo)致cpu的利用率不高。


為了合理最大限度的使用系統(tǒng)資源同時(shí)也要保證的程序的高性能,可以給CPU密集型任務(wù)和IO密集型任務(wù)配置一些線程數(shù)。
  • CPU密集型:線程個(gè)數(shù)為CPU核數(shù)。這幾個(gè)線程可以并行執(zhí)行,不存在線程切換到開銷,提高了cpu的利用率的同時(shí)也減少了切換線程導(dǎo)致的性能損耗

  • IO密集型:線程個(gè)數(shù)為CPU核數(shù)的兩倍。到其中的線程在IO操作的時(shí)候,其他線程可以繼續(xù)用cpu,提高了cpu的利用率。

看完上述內(nèi)容,你們掌握J(rèn)ava并發(fā)編程中線程池工作原理的示例分析的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!


網(wǎng)站名稱:Java并發(fā)編程中線程池工作原理的示例分析
網(wǎng)頁(yè)網(wǎng)址:http://weahome.cn/article/ppphcd.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部