Java多線程--建立和使用線程池

使用線程池的目的:api

  • 線程是稀缺資源,不能頻繁的建立。ide

  • 解耦做用;線程的建立於執行徹底分開,方便維護。ui

  • 應當將其放入一個池子中,能夠給其餘任務進行復用。spa

建立線程池的方式:線程

 在 JDK 1.5 以後推出了相關的 api,常見的建立線程池方式有如下三種:code

  • Executors.newCachedThreadPool():無限線程池。orm

  • Executors.newFixedThreadPool(nThreads):建立固定大小的線程池。blog

  • Executors.newSingleThreadExecutor():建立單個線程的線程池。隊列

可是在阿里巴巴開發規約中對線程池的建立有如下幾個強制要求:資源

能夠看到規約是不容許使用Executors直接建立線程池的,而要經過ThreadPoolExecutor的方式建立

1 public static ExecutorService newCachedThreadPool() {
2         return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
3                                       60L, TimeUnit.SECONDS,
4                                       new SynchronousQueue<Runnable>());
5 }

咱們看到這三種方式的源碼也是經過ThreadPoolExecutor的方式來建立的,接下來咱們看一下ThreadPoolExecutor的API

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

 

這幾個核心參數的做用:

  • corePoolSize 爲線程池的基本大小。

  • maximumPoolSize 爲線程池最大線程大小。

  • keepAliveTime 和 unit 則是線程空閒後的存活時間。

  • workQueue 用於存聽任務的阻塞隊列。

  • handler 當隊列和最大線程池都滿了以後的飽和策略。

 線程池大小建立的原則:

  • IO 密集型任務:因爲線程並非一直在運行,因此能夠儘量的多配置線程,好比 CPU 個數 * 2

  • CPU 密集型任務(大量複雜的運算)應當分配較少的線程,好比 CPU 個數至關的大小。

經過SpringBoot管理線程池:

 1 @Configuration
 2 public class TreadPoolConfig {
 3 
 4 
 5     /**
 6      * 消費隊列線程
 7      * @return
 8      */
 9     @Bean(value = "consumerQueueThreadPool")
10     public ExecutorService buildConsumerQueueThreadPool(){
11         ThreadFactory namedThreadFactory = new ThreadFactoryBuilder()
12                 .setNameFormat("consumer-queue-thread-%d").build();
13 
14         ExecutorService pool = new ThreadPoolExecutor(5, 5, 0L, TimeUnit.MILLISECONDS,
15                 new ArrayBlockingQueue<Runnable>(5),namedThreadFactory,new ThreadPoolExecutor.AbortPolicy());
16 
17         return pool ;
18     }
19 
20 
21 
22 }

使用:

 1   @Resource(name = "consumerQueueThreadPool")
 2     private ExecutorService consumerQueueThreadPool;
 3 
 4 
 5     @Override
 6     public void execute() {
 7 
 8         //消費隊列
 9         for (int i = 0; i < 5; i++) {
10             consumerQueueThreadPool.execute(new ConsumerQueueThread());
11         }
12 
13     }

其實也挺簡單,就是建立了一個線程池的 bean,在使用時直接從 Spring 中取出便可。

相關文章
相關標籤/搜索