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