亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

java多線程學(xué)習(xí)筆記之自定義線程池

 更新時(shí)間:2017年09月01日 09:25:00   作者:eleven_yw  
本篇文章主要介紹了java多線程學(xué)習(xí)筆記之自定義線程池 ,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

當(dāng)我們使用 線程池的時(shí)候,可以使用 newCachedThreadPool()或者 newFixedThreadPool(int)等方法,其實(shí)我們深入到這些方法里面,就可以看到它們的是實(shí)現(xiàn)方式是這樣的。

 public static ExecutorService newCachedThreadPool() {
     return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                    60L, TimeUnit.SECONDS,
                    new SynchronousQueue<Runnable>());
}
public static ExecutorService newFixedThreadPool(int nThreads) {
     return new ThreadPoolExecutor(nThreads, nThreads,
                    0L, TimeUnit.MILLISECONDS,
                    new LinkedBlockingQueue<Runnable>());
 }

包括其他幾種不同類(lèi)型的線程池,其實(shí)都是通過(guò) ThreadPoolExecutor這個(gè)核心類(lèi)來(lái)創(chuàng)建的,如果我們要自定義線程池,那么也是通過(guò)這個(gè)類(lèi)來(lái)實(shí)現(xiàn)的。

該類(lèi)有四個(gè)構(gòu)造方法,查看源碼可以看到,頭三個(gè)構(gòu)造方法,其實(shí)都是調(diào)用的第四個(gè)構(gòu)造方法,所以我們就解釋一下第四個(gè)構(gòu)造方法的參數(shù)含義。

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

corePoolSize:核心線程池的大小,在線程池被創(chuàng)建之后,其實(shí)里面是沒(méi)有線程的。(當(dāng)然,調(diào)用prestartAllCoreThreads()或者prestartCoreThread()方法會(huì)預(yù)創(chuàng)建線程,而不用等著任務(wù)的到來(lái))。當(dāng)有任務(wù)進(jìn)來(lái)的時(shí)候,才會(huì)創(chuàng)建線程。當(dāng)線程池中的線程數(shù)量達(dá)到corePoolSize之后,就把任務(wù)放到 緩存隊(duì)列當(dāng)中。(就是 workQueue)。

maximumPoolSize:最大線程數(shù)量是多少。它標(biāo)志著這個(gè)線程池的最大線程數(shù)量。如果沒(méi)有最大數(shù)量,當(dāng)創(chuàng)建的線程數(shù)量達(dá)到了 某個(gè)極限值,到最后內(nèi)存肯定就爆掉了。

keepAliveTime:當(dāng)線程沒(méi)有任務(wù)時(shí),最多保持的時(shí)間,超過(guò)這個(gè)時(shí)間就被終止了。默認(rèn)情況下,只有 線程池中線程數(shù)量 大于 corePoolSize時(shí),keepAliveTime值才會(huì)起作用。也就說(shuō)說(shuō),只有在線程池線程數(shù)量超出corePoolSize了。我們才會(huì)把超時(shí)的空閑線程給停止掉。否則就保持線程池中有 corePoolSize 個(gè)線程就可以了。

Unit:參數(shù)keepAliveTime的時(shí)間單位,就是 TimeUnit類(lèi)當(dāng)中的幾個(gè)屬性。

如下圖:

workQueue:用來(lái)存儲(chǔ)待執(zhí)行任務(wù)的隊(duì)列,不同的線程池它的隊(duì)列實(shí)現(xiàn)方式不同(因?yàn)檫@關(guān)系到排隊(duì)策略的問(wèn)題)比如有以下幾種

ArrayBlockingQueue:基于數(shù)組的隊(duì)列,創(chuàng)建時(shí)需要指定大小。

LinkedBlockingQueue:基于鏈表的隊(duì)列,如果沒(méi)有指定大小,則默認(rèn)值是 Integer.MAX_VALUE。(newFixedThreadPool和newSingleThreadExecutor使用的就是這種隊(duì)列)。

SynchronousQueue:這種隊(duì)列比較特殊,因?yàn)椴慌抨?duì)就直接創(chuàng)建新線程把任務(wù)提交了。(newCachedThreadPool使用的就是這種隊(duì)列)。

threadFactory:線程工廠,用來(lái)創(chuàng)建線程。

Handler:拒絕執(zhí)行任務(wù)時(shí)的策略,一般來(lái)講有以下四種策略,

(1) ThreadPoolExecutor.AbortPolicy 丟棄任務(wù),并拋出 RejectedExecutionException 異常。

(2) ThreadPoolExecutor.CallerRunsPolicy:該任務(wù)被線程池拒絕,由調(diào)用 execute方法的線程執(zhí)行該任務(wù)。

(3) ThreadPoolExecutor.DiscardOldestPolicy : 拋棄隊(duì)列最前面的任務(wù),然后重新嘗試執(zhí)行任務(wù)。

(4) ThreadPoolExecutor.DiscardPolicy,丟棄任務(wù),不過(guò)也不拋出異常。

看一個(gè)demo ,示例代碼地址:src/thread_runnable/CustomThreadPool.java

class CustomTask implements Runnable{
  private int id;
  public CustomTask(int id) {
    this.id = id;
  }

  @Override
  public void run() {
    // TODO Auto-generated method stub
    System.out.println("#" + id + "  threadId=" + Thread.currentThread().getName() );
    try {
      TimeUnit.MILLISECONDS.sleep(100);
    }catch(InterruptedException e){
      e.printStackTrace();
    }
  }
  
}

public class CustomThreadPool {
  public static void main(String[] args) {
    // TODO Auto-generated method stub
      BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(10);
      ThreadPoolExecutor pool = new ThreadPoolExecutor(3, 5, 60, TimeUnit.MICROSECONDS, queue);
      
      for (int i=0; i<7; i++){
        Runnable task = new CustomTask(i);
        pool.execute(task);
      }
      
      pool.shutdown();
  }

}

輸出結(jié)果: 

 

從這個(gè)例子,可以看出,雖然我們有7個(gè)任務(wù),但是實(shí)際上,只有三個(gè)線程在運(yùn)行。

那么當(dāng)我們提交任務(wù)給線程池之后,它的處理策略是什么呢?

 

(1),如果當(dāng)前線程池線程數(shù)目小于 corePoolSize(核心池還沒(méi)滿(mǎn)呢),那么就創(chuàng)建一個(gè)新線程去處理任務(wù)。

(2),如果核心池已經(jīng)滿(mǎn)了,來(lái)了一個(gè)新的任務(wù)后,會(huì)嘗試將其添加到任務(wù)隊(duì)列中,如果成功,則等待空閑線程將其從隊(duì)列中取出并且執(zhí)行,如果隊(duì)列已經(jīng)滿(mǎn)了,則繼續(xù)下一步。

(3),此時(shí),如果線程池線程數(shù)量 小于 maximumPoolSize,則創(chuàng)建一個(gè)新線程執(zhí)行任務(wù),否則,那就說(shuō)明線程池到了最大飽和能力了,沒(méi)辦法再處理了,此時(shí)就按照拒絕策略來(lái)處理。(就是構(gòu)造函數(shù)當(dāng)中的Handler對(duì)象)。

(4),如果線程池的線程數(shù)量大于corePoolSize,則當(dāng)某個(gè)線程的空閑時(shí)間超過(guò)了keepAliveTime,那么這個(gè)線程就要被銷(xiāo)毀了,直到線程池中線程數(shù)量不大于corePoolSize為止。

舉個(gè)通俗易懂的例子,公司要設(shè)立一個(gè)項(xiàng)目組來(lái)處理某些任務(wù),hr部門(mén)給的人員編制是10個(gè)人(corePoolSize)。同時(shí)給他們專(zhuān)門(mén)設(shè)置了一間有15個(gè)座位(maximumPoolSize)的辦公室。最開(kāi)始的時(shí)候來(lái)了一個(gè)任務(wù),就招聘一個(gè)人。就這樣,一個(gè)一個(gè)的招聘,招滿(mǎn)了十個(gè)人,不斷有新的任務(wù)安排給這個(gè)項(xiàng)目組,每個(gè)人也在不停的接任務(wù)干活。不過(guò)后來(lái)任務(wù)越來(lái)越多,十個(gè)人無(wú)法處理完了。其他的任務(wù)就只能在走廊外面排隊(duì)了。后來(lái)任務(wù)越來(lái)越多,走廊的排隊(duì)隊(duì)伍也擠不下。然后只好找找一些臨時(shí)工來(lái)幫助完成任務(wù)。因?yàn)檗k公室只有15個(gè)座位,所以它們最多也就只能找5個(gè)臨時(shí)工。可是任務(wù)依舊越來(lái)越多,根本處理不完,那沒(méi)辦法,這個(gè)項(xiàng)目組只好拒絕再接新任務(wù)。(拒絕的方式就是 Handler),最后任務(wù)漸漸的少了,大家都比較清閑了。所以就決定看大家表現(xiàn),誰(shuí)表現(xiàn)不好,誰(shuí)就被清理出這個(gè)辦公室(空閑時(shí)間超過(guò) keepAliveTime),直到 辦公室只剩下10個(gè)人(corePoolSize),維持固定的人員編制為止。

關(guān)于線程池,ThreadPoolExecutor還提供了一些需要注意的方法:

(1) shutdown(),平滑的關(guān)閉線程池。(如果還有未執(zhí)行完的任務(wù),就等待它們執(zhí)行完)。

(2) shutdownNow()。簡(jiǎn)單粗暴的關(guān)閉線程池。(沒(méi)有執(zhí)行完的任務(wù)也直接關(guān)閉)。

(3) setCorePoolSize()。設(shè)置/更改核心池的大小。

(4) setMaximumPoolSize(),設(shè)置/更改線程池中最大線程的數(shù)量限制。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • MyBatis配置文件元素示例詳解

    MyBatis配置文件元素示例詳解

    在MyBatis框架的核心配置文件中,<configuration>元素是配置文件的根元素,其他元素都要在<contiguration>元素內(nèi)配置,這篇文章主要介紹了MyBatis配置文件元素,需要的朋友可以參考下
    2023-06-06
  • java動(dòng)態(tài)口令登錄實(shí)現(xiàn)過(guò)程詳解

    java動(dòng)態(tài)口令登錄實(shí)現(xiàn)過(guò)程詳解

    這篇文章主要介紹了java動(dòng)態(tài)口令登錄實(shí)現(xiàn)過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-07-07
  • 基于Java代碼操作Redis過(guò)程詳解

    基于Java代碼操作Redis過(guò)程詳解

    這篇文章主要介紹了基于Java代碼操作Redis過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-10-10
  • ElasticSearch整合SpringBoot搭建配置

    ElasticSearch整合SpringBoot搭建配置

    這篇文章主要為大家介紹了ElasticSearch整合SpringBoot搭建配置詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • SpringBoot中基于AOP和Semaphore實(shí)現(xiàn)API限流

    SpringBoot中基于AOP和Semaphore實(shí)現(xiàn)API限流

    調(diào)用速率限制是 Web API 中的常見(jiàn)要求,旨在防止濫用并確保公平使用資源,借助Spring Boot 中的 AOP,我們可以通過(guò)攔截方法調(diào)用并限制在特定時(shí)間范圍內(nèi)允許的請(qǐng)求數(shù)量來(lái)實(shí)現(xiàn)速率限制,需要的朋友可以參考下
    2024-10-10
  • Spring Gateway自定義請(qǐng)求參數(shù)封裝的實(shí)現(xiàn)示例

    Spring Gateway自定義請(qǐng)求參數(shù)封裝的實(shí)現(xiàn)示例

    這篇文章主要介紹了Spring Gateway自定義請(qǐng)求參數(shù)封裝的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • Java IO之字節(jié)輸入輸出流詳解

    Java IO之字節(jié)輸入輸出流詳解

    這篇文章主要為大家介紹了Java IO之字節(jié)輸入輸出流,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-01-01
  • IntelliJ IDEA(2019)安裝破解及HelloWorld案例(圖文)

    IntelliJ IDEA(2019)安裝破解及HelloWorld案例(圖文)

    這篇文章主要介紹了IntelliJ IDEA(2019)安裝破解及HelloWorld案例(圖文),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • Java 生成隨機(jī)字符串?dāng)?shù)組的實(shí)例詳解

    Java 生成隨機(jī)字符串?dāng)?shù)組的實(shí)例詳解

    這篇文章主要介紹了Java 生成隨機(jī)字符串?dāng)?shù)組的實(shí)例詳解的相關(guān)資料,主要是利用Collections.sort()方法對(duì)泛型為String的List 進(jìn)行排序,需要的朋友可以參考下
    2017-08-08
  • 使用Jitpack發(fā)布開(kāi)源Java庫(kù)的詳細(xì)流程

    使用Jitpack發(fā)布開(kāi)源Java庫(kù)的詳細(xì)流程

    這篇文章主要介紹了使用Jitpack發(fā)布開(kāi)源Java庫(kù)的詳細(xì)流程,本文通過(guò)圖文實(shí)例代碼相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-02-02

最新評(píng)論