欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java 線程池ExecutorService詳解及實(shí)例代碼

 更新時(shí)間:2016年11月30日 15:47:24   作者:楊龍飛的博客  
這篇文章主要介紹了Java 線程池ExecutorService詳解及實(shí)例代碼的相關(guān)資料,線程池減少在創(chuàng)建和銷毀線程上所花的時(shí)間以及系統(tǒng)資源的開(kāi)銷.如果不使用線程池,有可能造成系統(tǒng)創(chuàng)建大量線程而導(dǎo)致消耗系統(tǒng)內(nèi)存以及”過(guò)度切換“

Java 線程池ExecutorService

1.線程池 

1.1什么情況下使用線程池

  1. 單個(gè)任務(wù)處理的時(shí)間比較短.
  2. 將需處理的任務(wù)的數(shù)量大.

1.2使用線程池的好處

  1. 減少在創(chuàng)建和銷毀線程上所花的時(shí)間以及系統(tǒng)資源的開(kāi)銷.
  2. 如果不使用線程池,有可能造成系統(tǒng)創(chuàng)建大量線程而導(dǎo)致消耗系統(tǒng)內(nèi)存以及”過(guò)度切換”;

2.ExecutorService和Executors

2.1簡(jiǎn)介

ExecutorService是一個(gè)接口,繼承了Executor,

public interface ExecutorService extend Executor{
}

Executor也是一個(gè)接口,該接口只包含一個(gè)方法:

public interface Executor {
  void execute(Runnable command);
}

Java里面的線程池的頂級(jí)接口是Excutor,但是嚴(yán)格意義上來(lái)說(shuō)>>Exector并不是一個(gè)線程池,而只是一個(gè)執(zhí)行線程的工具,真正的線程>池接口是ExecutorService.

3.Executors

它是一個(gè)靜態(tài)工廠類,它能生產(chǎn)不同類型的線程池,部分源碼如下:

public class Executors {
//newFixedThreadPool
public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());
}
//newCacheThreadPool
 public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,60L, TimeUnit.SECONDS,new SynchronousQueue<Runnable>());
  }
 //newScheduledThreadPool
  public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
    return new ScheduledThreadPoolExecutor(corePoolSize);
  }
  //newStringooo
}

先看一個(gè)具體的例子,用例子來(lái)說(shuō)明它們之間的異同.

package thread;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;

/**
 * Created by yang on 16-7-11.
 */
public class Ch09_Executor {
  private static void run(ExecutorService threadPool) {
    for (int i = 1; i < 5; i++) {
      final int taskID=i;
      threadPool.execute(new Runnable() {
        @Override
        public void run() {
          for(int i=1;i<5;i++){
            try{
              Thread.sleep(20);
            }catch (InterruptedException e)
            {
              e.printStackTrace();
            }
            System.out.println("第"+taskID+"次任務(wù)的第"+i+"次執(zhí)行");
          }
        }
      });
    }
    threadPool.shutdown();

  }

  public static void main(String[] args) {
    //創(chuàng)建可以容納3個(gè)線程的線程池
    ExecutorService fixedThreadPool= Executors.newFixedThreadPool(3);
    //線程池的大小會(huì)根據(jù)執(zhí)行的任務(wù)動(dòng)態(tài)的分配
    ExecutorService cacheThreadPool=Executors.newCachedThreadPool();
    //創(chuàng)建單個(gè)線程的線程池,如果當(dāng)前線程在執(zhí)行任務(wù)時(shí)突然中斷,則會(huì)創(chuàng)建一個(gè)新的線程替換它繼續(xù)執(zhí)行.
    ExecutorService singleThreadPool=Executors.newSingleThreadExecutor();
    //效果類似于Timer定時(shí)器
    ScheduledExecutorService scheduledThreadPool=Executors.newScheduledThreadPool(3);
    // run(fixedThreadPool); //(1)
    //run(cacheThreadPool); //(2)
    // run(singleThreadPool); //(3)
    // run(scheduledThreadPool); //(4)
  }
}

4. 4種常用的線程池

4.1 CachedThreadPool

CachedThreadPool會(huì)創(chuàng)建一個(gè)緩存區(qū),將初始化的線程緩存起來(lái),會(huì)終止并且從緩存中移除已有6秒未被使用的線程.
如果線程有可用,就使用之前創(chuàng)建好的線程.如果線程沒(méi)有可用的,就新創(chuàng)建線程.

.重用:

緩存型池子,先看看池中有沒(méi)有以前建立的線程,如果有,就reuse,如果沒(méi)有,就新建一個(gè)新的線程加入池中,

使用場(chǎng)景:

緩存型池子通常用于執(zhí)行一些生存期很短的異步型任務(wù),因此在一些面向連接的Daemon型SERVER中用地不多.

超時(shí):

能reuse的線程,必須是timeout IDLE內(nèi)的池中線程,缺省timeout是60s,超過(guò)這個(gè)IDLE時(shí)長(zhǎng),線程實(shí)例將被終止及移除池.

結(jié)束:

放入CachedThreadPool的線程不必?fù)?dān)心其結(jié)束,超過(guò)TIMEOUT不活動(dòng),其會(huì)被自動(dòng)終止.

實(shí)例解說(shuō):

去掉(2)的注釋,運(yùn)行,得到的運(yùn)行結(jié)果如下:

第1次任務(wù)的第1次執(zhí)行
第3次任務(wù)的第1次執(zhí)行
第2次任務(wù)的第1次執(zhí)行
第4次任務(wù)的第1次執(zhí)行
第3次任務(wù)的第2次執(zhí)行
第1次任務(wù)的第2次執(zhí)行
第2次任務(wù)的第2次執(zhí)行
第4次任務(wù)的第2次執(zhí)行
第3次任務(wù)的第3次執(zhí)行
第1次任務(wù)的第3次執(zhí)行
第2次任務(wù)的第3次執(zhí)行
第4次任務(wù)的第3次執(zhí)行
第3次任務(wù)的第4次執(zhí)行
第2次任務(wù)的第4次執(zhí)行
第4次任務(wù)的第4次執(zhí)行
第1次任務(wù)的第4次執(zhí)行

從結(jié)果可以看出,4個(gè)任務(wù)是交替執(zhí)行的.

4.2FixedThreadPool

在FixedThreadPool中,有一個(gè)固定大小的池,

如果當(dāng)前需要執(zhí)行的任務(wù)超過(guò)池大小,那么多出去的任務(wù)處于等待狀態(tài),直到有空閑下來(lái)的線程執(zhí)行任務(wù)。
如果當(dāng)前需要執(zhí)行的任務(wù)小于池大小,空閑線程不會(huì)被銷毀.

重用:

fixedThreadPool與cacheThreadPool差不多,也是能reuse就用,但不能隨時(shí)建新的線程

固定數(shù)目

其獨(dú)特之處在于,任意時(shí)間點(diǎn),最多只能有固定數(shù)目的活動(dòng)線程存在,此時(shí)如果有新的線程要建立,只能放在另外的隊(duì)列中等待,直到當(dāng)前的線程中某個(gè)線程終止直接被移出池子

超時(shí):

和cacheThreadPool不同,F(xiàn)ixedThreadPool沒(méi)有IDLE機(jī)制

使用場(chǎng)景:

所以FixedThreadPool多數(shù)針對(duì)一些很穩(wěn)定很固定的正規(guī)并發(fā)線程,多用于服務(wù)器

源碼分析:

從方法的源代碼看,cache池和fixed 池調(diào)用的是同一個(gè)底層池,只不過(guò)參數(shù)不同.
fixed池線程數(shù)固定,并且是0秒IDLE(無(wú)IDLE)
cache池線程數(shù)支持0-Integer.MAX_VALUE(顯然完全沒(méi)考慮主機(jī)的資源承受能力),60秒IDLE

實(shí)例解說(shuō):

去掉(1)的注釋,運(yùn)行結(jié)果如下:

第1次任務(wù)的第1次執(zhí)行
第3次任務(wù)的第1次執(zhí)行
第2次任務(wù)的第1次執(zhí)行
第1次任務(wù)的第2次執(zhí)行
第3次任務(wù)的第2次執(zhí)行
第2次任務(wù)的第2次執(zhí)行
第1次任務(wù)的第3次執(zhí)行
第3次任務(wù)的第3次執(zhí)行
第2次任務(wù)的第3次執(zhí)行
第1次任務(wù)的第4次執(zhí)行
第3次任務(wù)的第4次執(zhí)行
第2次任務(wù)的第4次執(zhí)行
第4次任務(wù)的第1次執(zhí)行
第4次任務(wù)的第2次執(zhí)行
第4次任務(wù)的第3次執(zhí)行
第4次任務(wù)的第4次執(zhí)行

創(chuàng)建了一個(gè)固定大小的線程池,容量是為3,然后循環(huán)執(zhí)行4個(gè)任務(wù),由輸出結(jié)果可以看出,前3個(gè)任務(wù)首先執(zhí)行完,然后空閑下來(lái)的線程去執(zhí)行第4個(gè)任務(wù).

4.3SingleThreadExecutor

  1. SingleThreadExector得到的是一個(gè)單個(gè)線程,這個(gè)線程會(huì)保證你的任務(wù)執(zhí)行完成.
  2. 單例線程,任意時(shí)間池中只能有一個(gè)線程
  3. 如果當(dāng)前線程意外終止,會(huì)創(chuàng)建一個(gè)新的線程繼續(xù)執(zhí)行任務(wù),這和我們直接創(chuàng)建線程不同,也和newFixedThreadPool(1)不同.
  4. 用的是和cache池和fixed池相同的底層池,但線程數(shù)目是1-1,0秒IDLE(無(wú)IDLE)

去掉(3)注釋. 看執(zhí)行結(jié)果如下:

第1次任務(wù)的第1次執(zhí)行
第1次任務(wù)的第2次執(zhí)行
第1次任務(wù)的第3次執(zhí)行
第1次任務(wù)的第4次執(zhí)行
第2次任務(wù)的第1次執(zhí)行
第2次任務(wù)的第2次執(zhí)行
第2次任務(wù)的第3次執(zhí)行
第2次任務(wù)的第4次執(zhí)行
第3次任務(wù)的第1次執(zhí)行
第3次任務(wù)的第2次執(zhí)行
第3次任務(wù)的第3次執(zhí)行
第3次任務(wù)的第4次執(zhí)行
第4次任務(wù)的第1次執(zhí)行
第4次任務(wù)的第2次執(zhí)行
第4次任務(wù)的第3次執(zhí)行
第4次任務(wù)的第4次執(zhí)行

四個(gè)任務(wù)是順序執(zhí)行的.

4.4 ScheduledThreadPool

ScheduledThreadPool是一個(gè)固定大小的線程池,與FixedThreadPool類似,執(zhí)行的任務(wù)是定時(shí)任務(wù).
去掉(4)的注釋得到的結(jié)果和FixedThreadPool得到的結(jié)果相同,ScheduledThreadPool的主要沒(méi)有在這里,而是定時(shí)任務(wù),看下面這個(gè)例子:

package thread;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * Created by yang on 16-7-11.
 */
public class MyScheduledTask implements Runnable {
  private String tname;
  public MyScheduledTask(String name){
    this.tname=name;
  }
  public void run(){
    System.out.println(tname+"任務(wù)時(shí)延時(shí)2秒執(zhí)行!");
  }

  public static void main(String[] args) {
    ScheduledExecutorService scheduledPool= Executors.newScheduledThreadPool(2);
    ScheduledExecutorService singSchedulePool=Executors.newSingleThreadScheduledExecutor();
    MyScheduledTask mt1=new MyScheduledTask("mt1");
    MyScheduledTask mt2=new MyScheduledTask("mt2");
    //以scheduledThreadPool啟動(dòng)mt1任務(wù)執(zhí)行
    scheduledPool.schedule(mt1,2, TimeUnit.SECONDS);
    //用singlescheduledthreadPool啟動(dòng)mt2;
    singSchedulePool.schedule(mt2,2000,TimeUnit.MILLISECONDS);
    scheduledPool.shutdown();
    singSchedulePool.shutdown();
  }
}

結(jié)果:

mt1任務(wù)時(shí)延時(shí)2秒執(zhí)行!
mt2任務(wù)時(shí)延時(shí)2秒執(zhí)行!

在程序運(yùn)行2秒后,才會(huì)有結(jié)果顯示,說(shuō)明線程在2秒后執(zhí)行的.

感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!

相關(guān)文章

  • Eclipse?Jetty?server漏洞解決辦法

    Eclipse?Jetty?server漏洞解決辦法

    最近給?個(gè)客戶部署項(xiàng)?,但是客戶的安全稽核有點(diǎn)變態(tài),居然說(shuō) Eclipse Jetty Server?危漏洞,這篇文章主要給大家介紹了關(guān)于Eclipse?Jetty?server漏洞解決的相關(guān)資料,需要的朋友可以參考下
    2023-11-11
  • JAVA自定義注解實(shí)現(xiàn)接口/ip限流的示例代碼

    JAVA自定義注解實(shí)現(xiàn)接口/ip限流的示例代碼

    本文主要介紹了JAVA自定義注解實(shí)現(xiàn)接口/ip限流的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • struts2獲取服務(wù)器臨時(shí)目錄的方法

    struts2獲取服務(wù)器臨時(shí)目錄的方法

    這篇文章主要為大家詳細(xì)介紹了struts2獲取服務(wù)器臨時(shí)目錄的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-09-09
  • Spring Data Jpa的四種查詢方式詳解

    Spring Data Jpa的四種查詢方式詳解

    這篇文章主要介紹了Spring Data Jpa的四種查詢方式詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • SpringBoot之瘦身部署問(wèn)題

    SpringBoot之瘦身部署問(wèn)題

    這篇文章主要介紹了SpringBoot之瘦身部署問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • SpringCloud openfeign相互調(diào)用實(shí)現(xiàn)方法介紹

    SpringCloud openfeign相互調(diào)用實(shí)現(xiàn)方法介紹

    在springcloud中,openfeign是取代了feign作為負(fù)載均衡組件的,feign最早是netflix提供的,他是一個(gè)輕量級(jí)的支持RESTful的http服務(wù)調(diào)用框架,內(nèi)置了ribbon,而ribbon可以提供負(fù)載均衡機(jī)制,因此feign可以作為一個(gè)負(fù)載均衡的遠(yuǎn)程服務(wù)調(diào)用框架使用
    2022-11-11
  • Spring配置中transactionAttributes的使用方法介紹

    Spring配置中transactionAttributes的使用方法介紹

    這篇文章主要介紹了Spring配置中transactionAttributes的使用方法介紹的相關(guān)內(nèi)容,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-09-09
  • java基于mongodb實(shí)現(xiàn)分布式鎖的示例代碼

    java基于mongodb實(shí)現(xiàn)分布式鎖的示例代碼

    本文主要介紹了java基于mongodb實(shí)現(xiàn)分布式鎖,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • SpringBoot Tomcat啟動(dòng)實(shí)例代碼詳解

    SpringBoot Tomcat啟動(dòng)實(shí)例代碼詳解

    這篇文章主要介紹了SpringBoot Tomcat啟動(dòng)實(shí)例代碼詳解,需要的朋友可以參考下
    2017-09-09
  • 詳解Java引用類型的參數(shù)也是值傳遞

    詳解Java引用類型的參數(shù)也是值傳遞

    這篇文章主要介紹了Java引用類型的參數(shù)也是值傳遞,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03

最新評(píng)論