激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - 在spring boot中使用java線程池ExecutorService的講解

在spring boot中使用java線程池ExecutorService的講解

2019-06-23 11:42雙斜杠少年 Java教程

今天小編就為大家分享一篇關于在spring boot中使用java線程池ExecutorService的講解,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧

1. 認識java線程池

1.1 在什么情況下使用線程池?

  • 1.單個任務處理的時間比較短
  • 2.需處理的任務的數量大

1.2 使用線程池的好處:

  • 1.減少在創建和銷毀線程上所花的時間以及系統資源的開銷
  • 2.如不使用線程池,有可能造成系統創建大量線程而導致消耗完系統內存

1.3 線程池包括以下四個基本組成部分:

  • 1、線程池管理器(ThreadPool):用于創建并管理線程池,包括 創建線程池,銷毀線程池,添加新任務;
  • 2、工作線程(PoolWorker):線程池中線程,在沒有任務時處于等待狀態,可以循環的執行任務;
  • 3、任務接口(Task):每個任務必須實現的接口,以供工作線程調度任務的執行,它主要規定了任務的入口,任務執行完后的收尾工作,任務的執行狀態等;
  • 4、任務隊列(taskQueue):用于存放沒有處理的任務。提供一種緩沖機制。

1.4 線程池的核心參數

ThreadPoolExecutor 有四個構造方法,前三個都是調用最后一個(最后一個參數最全)

 public ThreadPoolExecutor(int corePoolSize,
               int maximumPoolSize,
               long keepAliveTime,
               TimeUnit unit,
               BlockingQueue<Runnable> workQueue) {
    this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
       Executors.defaultThreadFactory(), defaultHandler);
  }
  public ThreadPoolExecutor(int corePoolSize,
               int maximumPoolSize,
               long keepAliveTime,
               TimeUnit unit,
               BlockingQueue<Runnable> workQueue,
               ThreadFactory threadFactory) {
    this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
       threadFactory, defaultHandler);
  }
  public ThreadPoolExecutor(int corePoolSize,
               int maximumPoolSize,
               long keepAliveTime,
               TimeUnit unit,
               BlockingQueue<Runnable> workQueue,
               RejectedExecutionHandler handler) {
    this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
       Executors.defaultThreadFactory(), handler);
  }
  // 都調用它
  public ThreadPoolExecutor(// 核心線程數
  int corePoolSize, 
               // 最大線程數
               int maximumPoolSize, 
               // 閑置線程存活時間
               long keepAliveTime, 
               // 時間單位
               TimeUnit unit, 
               // 線程隊列
               BlockingQueue<Runnable> 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.corePoolSize = corePoolSize;
    this.maximumPoolSize = maximumPoolSize;
    this.workQueue = workQueue;
    this.keepAliveTime = unit.toNanos(keepAliveTime);
    this.threadFactory = threadFactory;
    this.handler = handler;
  }

主要參數

corePoolSize:核心線程數

  • 核心線程會一直存活,即使沒有任務需要執行
  • 當線程數小于核心線程數時,即使有線程空閑,線程池也會優先創建新線程處理
  • 設置allowCoreThreadTimeout=true(默認false)時,核心線程會超時關閉

maxPoolSize:最大線程數

  • 當線程數>=corePoolSize,且任務隊列已滿時。線程池會創建新線程來處理任務
  • 當線程數=maxPoolSize,且任務隊列已滿時,線程池會拒絕處理任務而拋出異常

keepAliveTime:線程空閑時間

  • 當線程空閑時間達到keepAliveTime時,線程會退出,直到線程數量=corePoolSize
  • 如果allowCoreThreadTimeout=true,則會直到線程數量=0

workQueue:一個阻塞隊列,用來存儲等待執行的任務,這個參數的選擇也很重要,會對線程池的運行過程產生重大影響,一般來說,這里的阻塞隊列有以下幾種選擇:

  • ArrayBlockingQueue;
  • LinkedBlockingQueue;
  • SynchronousQueue;

threadFactory:線程工廠,主要用來創建線程;

rejectedExecutionHandler:任務拒絕處理器,兩種情況會拒絕處理任務:

  • 當線程數已經達到maxPoolSize,切隊列已滿,會拒絕新任務
  • 當線程池被調用shutdown()后,會等待線程池里的任務執行完畢,再shutdown。如果在調用shutdown()和線程池真正shutdown之間提交任務,會拒絕新任務

當拒絕處理任務時線程池會調用rejectedExecutionHandler來處理這個任務。如果沒有設置默認是AbortPolicy,會拋出異常。ThreadPoolExecutor類有幾個內部實現類來處理這類情況:

  • AbortPolicy 丟棄任務,拋運行時異常
  • CallerRunsPolicy 執行任務
  • DiscardPolicy 忽視,什么都不會發生
  • DiscardOldestPolicy 從隊列中踢出最先進入隊列(最后一個執行)的任務
  • 實現RejectedExecutionHandler接口,可自定義處理器

1.5 Java線程池 ExecutorService

  • Executors.newCachedThreadPool 創建一個可緩存線程池,如果線程池長度超過處理需要,可靈活回收空閑線程,若無可回收,則新建線程。
  • Executors.newFixedThreadPool 創建一個定長線程池,可控制線程最大并發數,超出的線程會在隊列中等待。
  • Executors.newScheduledThreadPool 創建一個定長線程池,支持定時及周期性任務執行。
  • Executors.newSingleThreadExecutor 創建一個單線程化的線程池,它只會用唯一的工作線程來執行任務,保證所有任務按照指定順序(FIFO, LIFO, 優先級)執行。

備注:Executors只是一個工廠類,它所有的方法返回的都是ThreadPoolExecutor、ScheduledThreadPoolExecutor這兩個類的實例。

1.6 ExecutorService有如下幾個執行方法

  • executorService.execute(Runnable);這個方法接收一個Runnable實例,并且異步的執行
  • executorService.submit(Runnable)
  • executorService.submit(Callable)
  • executorService.invokeAny(…)
  • executorService.invokeAll(…)

execute(Runnable)

這個方法接收一個Runnable實例,并且異步的執行

executorService.execute(new Runnable() {
public void run() {
  System.out.println("Asynchronous task");
}
});
executorService.shutdown();

submit(Runnable)

submit(Runnable)和execute(Runnable)區別是前者可以返回一個Future對象,通過返回的Future對象,我們可以檢查提交的任務是否執行完畢,請看下面執行的例子:

Future future = executorService.submit(new Runnable() {
public void run() {
  System.out.println("Asynchronous task");
}
});
future.get(); //returns null if the task has finished correctly.

submit(Callable)

submit(Callable)和submit(Runnable)類似,也會返回一個Future對象,但是除此之外,submit(Callable)接收的是一個Callable的實現,Callable接口中的call()方法有一個返回值,可以返回任務的執行結果,而Runnable接口中的run()方法是void的,沒有返回值。請看下面實例:

Future future = executorService.submit(new Callable(){
public Object call() throws Exception {
  System.out.println("Asynchronous Callable");
  return "Callable Result";
}
});
System.out.println("future.get() = " + future.get());

如果任務執行完成,future.get()方法會返回Callable任務的執行結果。注意,future.get()方法會產生阻塞。

invokeAny(…)

invokeAny(…)方法接收的是一個Callable的集合,執行這個方法不會返回Future,但是會返回所有Callable任務中其中一個任務的執行結果。這個方法也無法保證返回的是哪個任務的執行結果,反正是其中的某一個。

ExecutorService executorService = Executors.newSingleThreadExecutor();
Set<Callable<String>> callables = new HashSet<Callable<String>>();
callables.add(new Callable<String>() {
public String call() throws Exception {
  return "Task 1";
}
});
callables.add(new Callable<String>() {
public String call() throws Exception {
  return "Task 2";
}
});
callables.add(new Callable<String>() {
  public String call() throws Exception {
  return "Task 3";
}
});
String result = executorService.invokeAny(callables);
System.out.println("result = " + result);
executorService.shutdown();

invokeAll(…)

invokeAll(…)與 invokeAny(…)類似也是接收一個Callable集合,但是前者執行之后會返回一個Future的List,其中對應著每個Callable任務執行后的Future對象。

List<Future<String>> futures = executorService.invokeAll(callables);
for(Future<String> future : futures){
System.out.println("future.get = " + future.get());
}
executorService.shutdown();

2. 在springBoot中使用java線程池ExecutorService

2.1 springBoot 的使用配置

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
 * 數據收集配置,主要作用在于Spring啟動時自動加載一個ExecutorService對象.
 * @author Bruce
 * @date 2017/2/22
 * update by Cliff at 2027/11/03
 */
@Configuration
public class ThreadPoolConfig {
  @Bean
  public ExecutorService getThreadPool(){
    return Executors.newFixedThreadPool();
  }
}

2.2 使用

在@service 中注入 ExecutorService 然后就可以直接用了。
  @Autowired
  private ExecutorService executorService;
public void test(){
    executorService.execute(new Runnable() {
      public void run() {
        System.out.println("Asynchronous task");
      }
    });
  }

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對服務器之家的支持。

延伸 · 閱讀

精彩推薦
  • Java教程java 中鎖的性能提高辦法

    java 中鎖的性能提高辦法

    這篇文章主要介紹了java 中鎖的性能提高辦法的相關資料,需要的朋友可以參考下...

    Java之家3092020-08-13
  • Java教程JavaWeb 實現驗證碼功能(demo)

    JavaWeb 實現驗證碼功能(demo)

    在 WEB-APP 中一般應用于:登錄、注冊、買某票、秒殺等場景,大家都接觸過這個驗證碼操作,今天小編通過實例代碼給大家講解javaweb實現驗證碼功能,需要...

    java教程網12832020-08-05
  • Java教程Java list.remove( )方法注意事項

    Java list.remove( )方法注意事項

    這篇文章主要介紹了Java list.remove( )方法注意事項,非常簡單易懂,需要的朋友可以參考下...

    妖久9552021-05-25
  • Java教程淺談Java(SpringBoot)基于zookeeper的分布式鎖實現

    淺談Java(SpringBoot)基于zookeeper的分布式鎖實現

    這篇文章主要介紹了Java(SpringBoot)基于zookeeper的分布式鎖實現,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的...

    LJY_SUPER5742021-07-21
  • Java教程SpringBoot引入Thymeleaf的實現方法

    SpringBoot引入Thymeleaf的實現方法

    這篇文章主要介紹了SpringBoot引入Thymeleaf的實現方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下...

    Bobby6472021-07-28
  • Java教程JAVA中通過自定義注解進行數據驗證的方法

    JAVA中通過自定義注解進行數據驗證的方法

    java 自定義注解驗證可自己添加所需要的注解,下面這篇文章主要給大家介紹了關于JAVA中通過自定義注解進行數據驗證的相關資料,文中通過示例代碼介紹...

    Decouple6362021-05-25
  • Java教程springboot ehcache 配置使用方法代碼詳解

    springboot ehcache 配置使用方法代碼詳解

    EhCache是一個比較成熟的Java緩存框架,Springboot對ehcache的使用非常支持,所以在Springboot中只需做些配置就可使用,且使用方式也簡易,今天給大家分享spri...

    m1719309529412912021-09-16
  • Java教程Java之Springcloud Feign組件詳解

    Java之Springcloud Feign組件詳解

    這篇文章主要介紹了Java之Springcloud Feign組件詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下...

    深情以改10322021-11-12
主站蜘蛛池模板: 免费激情视频网站 | 一级免费特黄视频 | 欧美一极视频 | 精品一区二区三区网站 | 日本高清在线免费 | 国产精品一区在线看 | 综合网日日天干夜夜久久 | 黄色网址在线视频 | 久久久久久久久久一本门道91 | 亚洲精品在线观看网站 | 久久色在线 | 嗯~啊~弄嗯~啊h高潮视频 | 国产美女爽到喷白浆的 | 国产99视频精品免视看9 | 福利免费在线 | 凹凸成人精品亚洲精品密奴 | 久久国产精品久久久久久 | 国产美女三级做爰 | 91看片在线观看视频 | 成人毛片100免费观看 | 国产成人强伦免费视频网站 | www亚洲成人 | 免费国产在线观看 | 农村少妇吞精夜夜爽视频 | 国产美女白浆 | 成人黄色短视频在线观看 | 日韩精品中文字幕一区二区 | 精品黑人一区二区三区国语馆 | 久久经典国产视频 | 国产一级二级视频 | 精品国产视频一区二区三区 | 污黄视频在线播放 | 黄色av一区二区三区 | 久久成年网 | 日韩欧美高清一区 | 日韩视频一区二区三区四区 | 免费日本一区二区 | 国内精品伊人久久久久网站 | 性爱视频免费 | 国产91精品久久久久久 | 999久久久久久 |