java創(chuàng)建線程池的7種實(shí)現(xiàn)方法
這 7 種實(shí)現(xiàn)方法分別是:
- Executors.newFixedThreadPool:創(chuàng)建一個(gè)固定大小的線程池,可控制并發(fā)的線程數(shù),超出的線程會(huì)在隊(duì)列中等待。
- Executors.newCachedThreadPool:創(chuàng)建一個(gè)可緩存的線程池,若線程數(shù)超過處理所需,緩存一段時(shí)間后會(huì)回收,若線程數(shù)不夠,則新建線程。
- Executors.newSingleThreadExecutor:創(chuàng)建單個(gè)線程數(shù)的線程池,它可以保證先進(jìn)先出的執(zhí)行順序。
- Executors.newScheduledThreadPool:創(chuàng)建一個(gè)可以執(zhí)行延遲任務(wù)的線程池。
- Executors.newSingleThreadScheduledExecutor:創(chuàng)建一個(gè)單線程的可以執(zhí)行延遲任務(wù)的線程池。
- Executors.newWorkStealingPool:創(chuàng)建一個(gè)搶占式執(zhí)行的線程池(任務(wù)執(zhí)行順序不確定)【JDK 1.8 添加】。
- ThreadPoolExecutor:手動(dòng)創(chuàng)建線程池的方式,它創(chuàng)建時(shí)最多可以設(shè)置 7 個(gè)參數(shù)。
一、用ExecutorService創(chuàng)建線程池
//1.創(chuàng)建一個(gè)大小為10的線程池 ExecutorService threadPool= Executors.newFixedThreadPool(10); //給線程池添加任務(wù) for (int i = 0;i < 10;i++){ threadPool.submit(new Runnable() { @Override public synchronized void run(){ //這里寫你的方法 log.info("開啟線程.."); } }); }
二、用ThreadPoolExecutor創(chuàng)建線程池
//1.創(chuàng)建一個(gè)大小為10的線程池 BlockingQueue queue = new LinkedBlockingQueue(); ThreadPoolExecutor executor= new ThreadPoolExecutor(10,Integer.MAX_VALUE,10L, TimeUnit.SECONDS,queue); //給線程池添加任務(wù) for (int i = 0;i < 10;i++){ executor.execute(new Runnable() { @Override public synchronized void run(){ //這里寫你的方法 log.info("開啟線程.."); } }); }
從根本上說ExecutorService算是通過ThreadPoolExecutor封裝出來的他們的底層其實(shí)是一樣的
ThreadPoolExecutor需要傳參,而ExecutorService有默認(rèn)值,值需要一個(gè)線程數(shù)量就可以了。
三、用ThreadPoolUtils工具類創(chuàng)建線程池
import com.google.common.util.concurrent.ThreadFactoryBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.concurrent.*; /** * 自定義線程創(chuàng)建工具類,創(chuàng)建線程池后不需要關(guān)閉 * * @author liangxn */ public class ThreadPoolUtils { private static final Logger LOGGER = LoggerFactory.getLogger(ThreadPoolUtils.class); private static ThreadPoolExecutor threadPool = null; private static final String POOL_NAME = "myPool"; // 等待隊(duì)列長(zhǎng)度 private static final int BLOCKING_QUEUE_LENGTH = 1000; // 閑置線程存活時(shí)間 private static final int KEEP_ALIVE_TIME = 5 * 1000; private ThreadPoolUtils() { throw new IllegalStateException("utility class"); } /** * 無返回值直接執(zhí)行 * * @param runnable 需要運(yùn)行的任務(wù) */ public static void execute(Runnable runnable) { getThreadPool().execute(runnable); } /** * 有返回值執(zhí)行 * 主線程中使用Future.get()獲取返回值時(shí),會(huì)阻塞主線程,直到任務(wù)執(zhí)行完畢 * * @param callable 需要運(yùn)行的任務(wù) */ public static <T> Future<T> submit(Callable<T> callable) { return getThreadPool().submit(callable); } /** * 停止線程池所有任務(wù) * @return */ public static synchronized void shutdownNow() { getThreadPool().shutdownNow(); } /** * 獲取線程池中活躍線程數(shù) * @return */ public static int getActiveCount() { return getThreadPool().getActiveCount(); } private static synchronized ThreadPoolExecutor getThreadPool() { if (threadPool == null) { // 獲取處理器數(shù)量 int cpuNum = Runtime.getRuntime().availableProcessors(); // 根據(jù)cpu數(shù)量,計(jì)算出合理的線程并發(fā)數(shù) int maximumPoolSize = cpuNum * 2 + 1; // 核心線程數(shù)、最大線程數(shù)、閑置線程存活時(shí)間、時(shí)間單位、線程隊(duì)列、線程工廠、當(dāng)前線程數(shù)已經(jīng)超過最大線程數(shù)時(shí)的異常處理策略 threadPool = new ThreadPoolExecutor(maximumPoolSize - 1, maximumPoolSize, KEEP_ALIVE_TIME, TimeUnit.MILLISECONDS, new LinkedBlockingDeque<>(BLOCKING_QUEUE_LENGTH), new ThreadFactoryBuilder().setNameFormat(POOL_NAME + "-%d").build(), new ThreadPoolExecutor.AbortPolicy() { @Override public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { LOGGER.warn("線程爆炸了,當(dāng)前運(yùn)行線程總數(shù):{},活動(dòng)線程數(shù):{}。等待隊(duì)列已滿,等待運(yùn)行任務(wù)數(shù):{}", e.getPoolSize(), e.getActiveCount(), e.getQueue().size()); } }); } return threadPool; } }
總結(jié)
到此這篇關(guān)于java創(chuàng)建線程池的7種實(shí)現(xiàn)方法的文章就介紹到這了,更多相關(guān)java創(chuàng)建線程池內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用Feign調(diào)用時(shí)添加驗(yàn)證信息token到請(qǐng)求頭方式
這篇文章主要介紹了使用Feign調(diào)用時(shí)添加驗(yàn)證信息token到請(qǐng)求頭方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03java8中的lambda表達(dá)式,看這篇絕對(duì)夠
這篇文章主要介紹了java8中的lambda表達(dá)式,看這篇絕對(duì)夠!具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03Java用Arrays.fill()初始化二維數(shù)組的實(shí)現(xiàn)
這篇文章主要介紹了Java用Arrays.fill()初始化二維數(shù)組的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01《阿里巴巴 Java開發(fā)手冊(cè)》讀后感小結(jié)
這篇文章主要介紹了《阿里巴巴 Java開發(fā)手冊(cè)》讀后感小結(jié),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-12-12@Async導(dǎo)致controller?404及失效原因解決分析
這篇文章主要為大家介紹了@Async導(dǎo)致controller?404失效問題解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07