摘要:本篇來看下線程池相關(guān)技術(shù)的實(shí)現(xiàn)和使用方式。時(shí)間單位這個(gè)線程池中線程處理任務(wù)的的任務(wù)隊(duì)列。上面的例子中我們向線程池中提交了一個(gè),并接受一個(gè)返回值。
本篇來看下java線程池相關(guān)技術(shù)的實(shí)現(xiàn)和使用方式。
0x01 線程的實(shí)現(xiàn)一開始我們想要實(shí)現(xiàn)多線程最通常的做法是:
new Thread(new Runnable() { public void run() { System.out.println("raw thread"); } }).start();
這種方式,這種實(shí)現(xiàn)方式也沒有什么不好,只是如果線程一多的話不好對(duì)所有的線程進(jìn)行統(tǒng)一管理。然后java有了線程池技術(shù),我們可以通過線程池技術(shù)來替換實(shí)現(xiàn)上面的方式。
0x02 線程池ExecutorService executorPool = Executors.newCachedThreadPool(); Futurefuture = executorPool.submit(new Callable () { public String call() throws Exception { return "future finish"; } }); try { System.out.println(future.get()); } catch (Exception e) { e.printStackTrace(); }
Executors有如下幾種方式創(chuàng)建線程:
newCachedThreadPool
newFixedThreadPool
newScheduledThreadPool
上面三種方式最終都是調(diào)用ThreadPoolExecutor的構(gòu)造函數(shù)進(jìn)行線程池的創(chuàng)建,只是傳入的參數(shù)不一樣,而實(shí)現(xiàn)不同的線程池對(duì)象。
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueueworkQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
corePoolSize:創(chuàng)建線程池時(shí)創(chuàng)建多少個(gè)線程。
maximumPoolSize:這個(gè)線程池中對(duì)多能有多少個(gè)線程。
keepAliveTime:當(dāng)線程數(shù)量超過corePoolSize時(shí),多余的空閑線程最大的存活時(shí)間。也就是說多余的線程在keepAliveTime時(shí)間還是沒有處理任何的任務(wù)將會(huì)被終止。
unit:時(shí)間單位
workQueue:這個(gè)線程池中線程處理任務(wù)的的任務(wù)隊(duì)列。
threadFactory:創(chuàng)建新線程的線程工廠。
handler:當(dāng)線程數(shù)量達(dá)到maximumPoolSize,對(duì)新加入的任務(wù)的處理策略。一般很少使用這個(gè)參數(shù)基本都采用默認(rèn)的handler。
上面的例子中我們向線程池中提交了一個(gè)Callable,并接受一個(gè)返回值Future。Callable可能會(huì)是一個(gè)非常耗時(shí)的操作但是使用方有不想阻塞等待其返回再繼續(xù)執(zhí)行,這時(shí)Callable執(zhí)行完后會(huì)將結(jié)果放到Future中,使用方可以在需要的時(shí)候去判斷是否Callable已經(jīng)執(zhí)行完成,如果完成就可以通過Future拿到其返回值。
0x03 ScheduledExecutorService任務(wù)定時(shí)調(diào)度線程的使用:
ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(); scheduledExecutorService.scheduleAtFixedRate(new Runnable() { public void run() { System.out.println("schedule task with fixed rate:" + System.currentTimeMillis()); } }, 2000, 1000, TimeUnit.MILLISECONDS); scheduledExecutorService.scheduleWithFixedDelay(new Runnable() { public void run() { System.out.println("schedule task with fixed delay:" + System.currentTimeMillis()); int count = Integer.MAX_VALUE; while (count-- > 0){ } System.out.println("time:" + System.currentTimeMillis()); } }, 2000, 1000, TimeUnit.MILLISECONDS);
ScheduledExecutorService有兩種定時(shí)調(diào)度的方式:
scheduleAtFixedRate:以固定速率進(jìn)行調(diào)度,意思是任何兩個(gè)被調(diào)度的任務(wù)之間的時(shí)間間隔是固定的。第二個(gè)任務(wù)的調(diào)度時(shí)間(開始執(zhí)行時(shí)間)= 第一個(gè)任務(wù)的調(diào)度時(shí)間 + 間隔時(shí)間
scheduleWithFixedDelay:第二個(gè)任務(wù)的調(diào)度時(shí)間 = 第一個(gè)任務(wù)的調(diào)度時(shí)間 + 第一個(gè)任務(wù)的執(zhí)行時(shí)間 + 間隔時(shí)間
0x04 Timer定時(shí)任務(wù)上面介紹了ScheduledExecutorService來做定時(shí)任務(wù),在編程的過程中還可以使用Timer來做定時(shí)任務(wù),代碼如下:
timer.scheduleAtFixedRate(new TimerTask() { @Override public void run() { try { doSomething(); } catch (Exception e) { System.out.println("timer excute exception", e); } } }, 1000 * 3, 1000);
其第一參數(shù)是一個(gè)TimerTask,第二第三個(gè)參數(shù)scheduledExecutorService.scheduleAtFixedRate這個(gè)調(diào)用的第二三個(gè)參數(shù)一致。
0x05 參考我覺得最好的參考還是閱讀相關(guān)源碼去理解Executor的使用方式,這樣自己才能理解的比較深入同時(shí)做到活學(xué)活用。
線程池的的核心實(shí)現(xiàn)ThreadPoolExecutor,想了解更多還是自己去look look源碼吧。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/66217.html
摘要:中的線程池是運(yùn)用場(chǎng)景最多的并發(fā)框架。才是真正的線程池。存放任務(wù)的隊(duì)列存放需要被線程池執(zhí)行的線程隊(duì)列。所以線程池的所有任務(wù)完成后,它最終會(huì)收縮到的大小。飽和策略一般情況下,線程池采用的是,表示無法處理新任務(wù)時(shí)拋出異常。 Java線程池 1. 簡(jiǎn)介 系統(tǒng)啟動(dòng)一個(gè)新線程的成本是比較高的,因?yàn)樗婕芭c操作系統(tǒng)的交互,這個(gè)時(shí)候使用線程池可以提升性能,尤其是需要?jiǎng)?chuàng)建大量聲明周期很短暫的線程時(shí)。Ja...
摘要:當(dāng)活動(dòng)線程核心線程非核心線程達(dá)到這個(gè)數(shù)值后,后續(xù)任務(wù)將會(huì)根據(jù)來進(jìn)行拒絕策略處理。線程池工作原則當(dāng)線程池中線程數(shù)量小于則創(chuàng)建線程,并處理請(qǐng)求。當(dāng)線程池中的數(shù)量等于最大線程數(shù)時(shí)默默丟棄不能執(zhí)行的新加任務(wù),不報(bào)任何異常。 spring-cache使用記錄 spring-cache的使用記錄,坑點(diǎn)記錄以及采用的解決方案 深入分析 java 線程池的實(shí)現(xiàn)原理 在這篇文章中,作者有條不紊的將 ja...
摘要:四種線程池的使用介紹的弊端及四種線程池的使用,線程池的作用線程池作用就是限制系統(tǒng)中執(zhí)行線程的數(shù)量。相比,提供的四種線程池的好處在于重用存在的線程,減少對(duì)象創(chuàng)建消亡的開銷,性能佳。延遲執(zhí)行描述創(chuàng)建一個(gè)定長(zhǎng)線程池,支持定時(shí)及周期性任務(wù)執(zhí)行。 java 四種線程池的使用 介紹new Thread的弊端及Java四種線程池的使用 1,線程池的作用 線程池作用就是限制系統(tǒng)中執(zhí)行線程的數(shù)量。 ...
系統(tǒng)啟動(dòng)一個(gè)線程的成本是比較高,使用線程池可以很好地提高性能,尤其是當(dāng)程序中需要?jiǎng)?chuàng)建大量生存期很短暫的線程時(shí) 線程池在系統(tǒng)啟動(dòng)時(shí)即創(chuàng)建大量空閑線程,將一個(gè)Runnable、Callable對(duì)象—–>傳給線程池—–>線程池啟動(dòng)里面的一個(gè)線程來執(zhí)行它們的run()或者call()方法———->當(dāng)線程執(zhí)行體執(zhí)行完成后,線程并不會(huì)死亡,而是再次返回線程池成為空閑狀態(tài),等待下一個(gè)Runnable、Calla...
摘要:高并發(fā)系列第篇文章。簡(jiǎn)單的說,在使用了線程池之后,創(chuàng)建線程變成了從線程池中獲取一個(gè)空閑的線程,然后使用,關(guān)閉線程變成了將線程歸還到線程池。如果調(diào)用了線程池的方法,線程池會(huì)提前把核心線程都創(chuàng)造好,并啟動(dòng)線程池允許創(chuàng)建的最大線程數(shù)。 java高并發(fā)系列第18篇文章。 本文主要內(nèi)容 什么是線程池 線程池實(shí)現(xiàn)原理 線程池中常見的各種隊(duì)列 自定義線程創(chuàng)建的工廠 常見的飽和策略 自定義飽和策略 ...
摘要:中的線程池運(yùn)用場(chǎng)景非常廣泛,幾乎所有的一步或者并發(fā)執(zhí)行程序都可以使用。代碼中如果執(zhí)行了方法,線程池會(huì)提前創(chuàng)建并啟動(dòng)所有核心線程。線程池最大數(shù)量線程池允許創(chuàng)建的線程最大數(shù)量。被稱為是可重用固定線程數(shù)的線程池。 Java中的線程池運(yùn)用場(chǎng)景非常廣泛,幾乎所有的一步或者并發(fā)執(zhí)行程序都可以使用。那么線程池有什么好處呢,以及他的實(shí)現(xiàn)原理是怎么樣的呢? 使用線程池的好處 在開發(fā)過程中,合理的使用線程...
閱讀 1319·2021-11-24 09:38
閱讀 3256·2021-11-22 12:03
閱讀 4158·2021-11-11 10:59
閱讀 2317·2021-09-28 09:36
閱讀 1032·2021-09-09 09:32
閱讀 3412·2021-08-05 10:00
閱讀 2528·2021-07-23 15:30
閱讀 2973·2019-08-30 13:12