Java和Spring中线程池创建方法
一、線程池定義
1.JDK中線程池類圖
Executor:父接口,所有線程池都實現了這個接口,里面有一個excute()方法用于執行線程
ExecutorService:線程池接口,繼承自Executor接口,供了生命周期管理的方法,返回 Future 對象,可以返回執行完的結果
ThreadPoolExecutor:線程池的具體實現類,一般使用ThreadPoolExecutor創建線程池
?
2.創建線程池的工具類
Executors:線程池的工具類,用于創建線程池,返回ExecutorService類型的線程池
1)public static ExecutorService newFiexedThreadPool(int Threads) :創建固定數目線程的線程池
2)public static ExecutorService newCachedThreadPool():創建一個可緩存的線程池,調用execute 將重用以前構造的線程(如果線程可用)。如果沒有可用的線程,則創建一個新線程并添加到池中。終止并從緩存中移除那些已有 60 秒鐘未被使用的線程
3)public static ExecutorService newSingleThreadExecutor():創建一個單線程化的Executor
4)public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize):調度型線程池
3.區別
1)Executor 接口定義了 execute()方法用來接收一個Runnable接口的對象,不接受返回的對象,而 ExecutorService 接口中的 submit()方法可以通過Future 對象接受Runnable和Callable接口的對象
2)ExecutorService 還提供用來控制線程池的方法。比如:調用 shutDown() 方法終止線程池
3)Executors 類提供工廠方法用來創建不同類型的線程池
4.線程池參數
corePoolSize:核心線程數
maximumPoolSize, //最大線程數
keepAliveTime:當線程數超過核心線程數,線程的最大存活時間
unit:keepAliveTime的時間單位
workQueue:阻塞隊列
threadFactory: 創建線程的工廠
handler:拒絕策略
5.線程池執行順序
1)當線程數小于 corePoolSize時,創建線程執行任務。
2)當線程數大于等于 corePoolSize并且 workQueue 沒有滿時,放入workQueue中
3)線程數大于等于 corePoolSize并且當 workQueue 滿時,新任務新建線程運行,線程總數要小于 maximumPoolSize
4)當線程總數等于 maximumPoolSize 并且 workQueue 滿了的時候執行 handler 的 rejectedExecution。也就是拒絕策略
6.拒絕訪問策略
ThreadPoolExecutor默認有四個拒絕策略:
1、ThreadPoolExecutor.AbortPolicy() 直接拋出異常RejectedExecutionException
2、ThreadPoolExecutor.CallerRunsPolicy() 直接調用run方法并且阻塞執行
3、ThreadPoolExecutor.DiscardPolicy() 直接丟棄后來的任務
4、ThreadPoolExecutor.DiscardOldestPolicy() 丟棄在隊列中隊首的任務
當然可以自己繼承RejectedExecutionHandler來寫拒絕策略.
?
二、線程池使用方法
1.Java JDK創建線程池的方法-ThreadPoolExecutor
1)使用ThreadPoolExecutor創建線程池
API如下所示:
public ThreadPoolExecutor(int corePoolSize, ?//核心線程數int maximumPoolSize, //最大線程數long keepAliveTime, ? //當線程數超過核心線程數,線程的最大存活時間TimeUnit unit, ? ? ? ?//keepAliveTime的時間單位BlockingQueue<Runnable> workQueue) //阻塞隊列容量{?this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,Executors.defaultThreadFactory(), defaultHandler); }所在包:java.util.concurrent.*
2)代碼實現:
3)結果展示:
?
2.Spring創建線程池方式-ThreadPoolTaskExecutor
所在包:package org.springframework.core.task;
創建線程池并注入spring容器,開啟@EnableAsync注解方便后續使用它@Async異步化調用
?
3.異步調用線程池線程方法-ThreadPoolTaskExecutor
1)代碼處使用
需要使用@Autowired裝配獲取注入的線程池對象
? @Autowiredprivate ThreadPoolTaskExecutor executor; ?/*** 根據活動id獲取指定活動,異步添加緩存操作*/@RequestMapping("/test9")public String testTaskExecutor() throws Throwable {log.info("進入方法:");//異步調用executor.execute(() -> {try {log.info("進入異步方法:");Thread.sleep(2000);jedisClusterClient.getJedisCluster().set("test9:async", "test"); ?} catch (InterruptedException e) {e.printStackTrace();}System.out.println("異步執行添加緩存:" + jedisClusterClient.getJedisCluster().get("test9:async"));});log.info("方法執行完畢");return "test";}執行結果:
可以看到異步執行是在方法執行完畢后才執行的,不是同步的,異步化成功
2)使用@Async注解異步調用
注意:@Async修飾的方法的實例必須注入spring容器中方能使用,代碼如下:
異步方法使用@Async調用:
執行結果:
可以看到結果也是異步化調用
總結
以上是生活随笔為你收集整理的Java和Spring中线程池创建方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MyBatis之PageHelper分页
- 下一篇: ThreadLocal原理