




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、為什么引入Executor線程池框架 new Thread()的缺點(diǎn) 每次new Thread()耗費(fèi)性能調(diào)用new Thread()創(chuàng)建的線程缺乏管理,被稱為野線程,而且可以無(wú)限制創(chuàng)建,之間相互競(jìng)爭(zhēng),會(huì)導(dǎo)致過(guò)多占用系統(tǒng)資源導(dǎo)致系統(tǒng)癱瘓。不利于擴(kuò)展,比如如定時(shí)執(zhí)行、定期執(zhí)行、線程中斷采用線程池的優(yōu)點(diǎn) 重用存在的線程,減少對(duì)象創(chuàng)建、消亡的開銷,性能佳可有效控制最大并發(fā)線程數(shù),提高系統(tǒng)資源的使用率,同時(shí)避免過(guò)多資源競(jìng)爭(zhēng),避免堵塞提供定時(shí)執(zhí)行、定期執(zhí)行、單線程、并發(fā)數(shù)控制等功能Executor的介紹 在Java 5之后,并發(fā)編程引入了一堆新的啟動(dòng)、調(diào)度和管理線程的API。Executor框架便是Ja
2、va 5中引入的, 其內(nèi)部使用了線程池機(jī)制,它在java.util.cocurrent 包下,通過(guò)該框架來(lái)控制線程的啟動(dòng)、執(zhí)行和關(guān)閉,可以簡(jiǎn)化并發(fā)編程的操作。因此,在Java 5之后,通過(guò)Executor來(lái)啟動(dòng)線程比使用Thread的start方法更好,除了更易管理,效率更好(用線程池實(shí)現(xiàn),節(jié)約開銷)外,還有關(guān)鍵的一點(diǎn):有助于避免this逃逸問(wèn)題如果我們?cè)跇?gòu)造器中啟動(dòng)一個(gè)線程,因?yàn)榱硪粋€(gè)任務(wù)可能會(huì)在構(gòu)造器結(jié)束之前開始執(zhí)行,此時(shí)可能會(huì)訪問(wèn)到初始化了一半的對(duì)象用Executor在構(gòu)造器中。Executor框架包括:線程池,Executor,Executors,ExecutorService,Com
3、pletionService,F(xiàn)uture,Callable等。Executors方法介紹 Executors工廠類 通過(guò)Executors提供四種線程池,newFixedThreadPool、newCachedThreadPool、newSingleThreadExecutor、newScheduledThreadPool。1.public static ExecutorService newFixedThreadPool(int nThreads)創(chuàng)建固定數(shù)目線程的線程池。2.public static ExecutorService newCachedThreadPool()創(chuàng)建一個(gè)可緩
4、存的線程池,調(diào)用execute將重用以前構(gòu)造的線程(如果線程可用)。如果現(xiàn)有線程沒(méi)有可用的,則創(chuàng)建一個(gè)新線 程并添加到池中。終止并從緩存中移除那些已有 60 秒鐘未被使用的線程。3.public static ExecutorService newSingleThreadExecutor()創(chuàng)建一個(gè)單線程化的Executor。4.public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)創(chuàng)建一個(gè)支持定時(shí)及周期性的任務(wù)執(zhí)行的線程池,多數(shù)情況下可用來(lái)替代Timer類。1.newFixedThread
5、Pool創(chuàng)建一個(gè)可重用固定線程數(shù)的線程池,以共享的無(wú)界隊(duì)列方式來(lái)運(yùn)行這些線程。 示例 ExecutorService executorService = Executors.newFixedThreadPool(5); for (int i = 0; i 20; i+) Runnable syncRunnable = new Runnable() Override public void run() Log.e(TAG, Thread.currentThread().getName(); ; executorService.execute(syncRunnable); 運(yùn)行結(jié)果:總共只會(huì)創(chuàng)建5
6、個(gè)線程, 開始執(zhí)行五個(gè)線程,當(dāng)五個(gè)線程都處于活動(dòng)狀態(tài),再次提交的任務(wù)都會(huì)加入隊(duì)列等到其他線程運(yùn)行結(jié)束,當(dāng)線程處于空閑狀態(tài)時(shí)會(huì)被下一個(gè)任務(wù)復(fù)用2.newCachedThreadPool創(chuàng)建一個(gè)可緩存線程池,如果線程池長(zhǎng)度超過(guò)處理需要,可靈活回收空閑線程 示例: ExecutorService executorService = Executors.newCachedThreadPool(); for (int i = 0; i 100; i+) Runnable syncRunnable = new Runnable() Override public void run() Log.e(TAG,
7、 Thread.currentThread().getName(); ; executorService.execute(syncRunnable); 運(yùn)行結(jié)果:可以看出緩存線程池大小是不定值,可以需要?jiǎng)?chuàng)建不同數(shù)量的線程,在使用緩存型池時(shí),先查看池中有沒(méi)有以前創(chuàng)建的線程,如果有,就復(fù)用.如果沒(méi)有,就新建新的線程加入池中,緩存型池子通常用于執(zhí)行一些生存期很短的異步型任務(wù)3.newScheduledThreadPool創(chuàng)建一個(gè)定長(zhǎng)線程池,支持定時(shí)及周期性任務(wù)執(zhí)行 schedule(Runnable command,long delay, TimeUnit unit)創(chuàng)建并執(zhí)行在給定延遲后啟用的一次
8、性操作示例:表示從提交任務(wù)開始計(jì)時(shí),5000毫秒后執(zhí)行 ScheduledExecutorService executorService = Executors.newScheduledThreadPool(5); for (int i = 0; i 20; i+) Runnable syncRunnable = new Runnable() Override public void run() Log.e(TAG, Thread.currentThread().getName(); ; executorService.schedule(syncRunnable, 5000, TimeUnit
9、.MILLISECONDS); 運(yùn)行結(jié)果和newFixedThreadPool類似,不同的是newScheduledThreadPool是延時(shí)一定時(shí)間之后才執(zhí)行scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnitunit) 創(chuàng)建并執(zhí)行一個(gè)在給定初始延遲后首次啟用的定期操作,后續(xù)操作具有給定的周期;也就是將在 initialDelay 后開始執(zhí)行,然后在initialDelay+period 后執(zhí)行,接著在 initialDelay + 2 * period 后執(zhí)行,依此類推 Schedule
10、dExecutorService executorService = Executors.newScheduledThreadPool(5); Runnable syncRunnable = new Runnable() Override public void run() Log.e(TAG, Thread.currentThread().getName(); ; executorService.scheduleAtFixedRate(syncRunnable, 5000, 3000, TimeUnit.MILLISECONDS);scheduleWithFixedDelay(Runnabl
11、e command, long initialDelay, long delay, TimeUnit unit) 創(chuàng)建并執(zhí)行一個(gè)在給定初始延遲后首次啟用的定期操作,隨后,在每一次執(zhí)行終止和下一次執(zhí)行開始之間都存在給定的延遲 ScheduledExecutorService executorService = Executors.newScheduledThreadPool(5); Runnable syncRunnable = new Runnable() Override public void run() Log.e(TAG, Thread.currentThread().getName(
12、); try Thread.sleep(1000); catch (InterruptedException e) e.printStackTrace(); ; executorService.scheduleWithFixedDelay(syncRunnable, 5000, 3000, TimeUnit.MILLISECONDS);4.newSingleThreadExecutor創(chuàng)建一個(gè)單線程化的線程池,它只會(huì)用唯一的工作線程來(lái)執(zhí)行任務(wù),保證所有任務(wù)按照指定順序(FIFO, LIFO, 優(yōu)先級(jí))執(zhí)行 ExecutorService executorService = Executors.
13、newSingleThreadExecutor(); for (int i = 0; i 20; i+) Runnable syncRunnable = new Runnable() Override public void run() Log.e(TAG, Thread.currentThread().getName(); ; executorService.execute(syncRunnable); 運(yùn)行結(jié)果:只會(huì)創(chuàng)建一個(gè)線程,當(dāng)上一個(gè)執(zhí)行完之后才會(huì)執(zhí)行第二個(gè)ExecutorService ExecutorService是一個(gè)接口,ExecutorService接口繼承了Executor
14、接口,定義了一些生命周期的方法。 public interface ExecutorService extends Executor void shutdown();/順次地關(guān)閉ExecutorService,停止接收新的任務(wù),等待所有已經(jīng)提交的任務(wù)執(zhí)行完畢之后,關(guān)閉ExecutorService List shutdownNow();/阻止等待任務(wù)啟動(dòng)并試圖停止當(dāng)前正在執(zhí)行的任務(wù),停止接收新的任務(wù),返回處于等待的任務(wù)列表 boolean isShutdown();/判斷線程池是否已經(jīng)關(guān)閉 boolean isTerminated();/如果關(guān)閉后所有任務(wù)都已完成,則返回 true。注意,除非
15、首先調(diào)用 shutdown 或 shutdownNow,否則 isTerminated 永不為 true。 boolean awaitTermination(long timeout, TimeUnit unit)/等待(阻塞)直到關(guān)閉或最長(zhǎng)等待時(shí)間或發(fā)生中斷,timeout - 最長(zhǎng)等待時(shí)間 ,unit - timeout 參數(shù)的時(shí)間單位 如果此執(zhí)行程序終止,則返回 true;如果終止前超時(shí)期滿,則返回 false Future submit(Callable task);/提交一個(gè)返回值的任務(wù)用于執(zhí)行,返回一個(gè)表示任務(wù)的未決結(jié)果的 Future。該 Future 的 get 方法在成功完成
16、時(shí)將會(huì)返回該任務(wù)的結(jié)果。 Future submit(Runnable task, T result);/提交一個(gè) Runnable 任務(wù)用于執(zhí)行,并返回一個(gè)表示該任務(wù)的 Future。該 Future 的 get 方法在成功完成時(shí)將會(huì)返回給定的結(jié)果。 Future submit(Runnable task);/提交一個(gè) Runnable 任務(wù)用于執(zhí)行,并返回一個(gè)表示該任務(wù)的 Future。該 Future 的 get 方法在成功 完成時(shí)將會(huì)返回 null ListFuture invokeAll(Collection? extends Callable tasks)/執(zhí)行給定的任務(wù),當(dāng)所有任
17、務(wù)完成時(shí),返回保持任務(wù)狀態(tài)和結(jié)果的 Future 列表。返回列表的所有元素的 Future.isDone() 為 true。 throws InterruptedException; ListFuture invokeAll(Collection? extends Callable tasks, long timeout, TimeUnit unit)/執(zhí)行給定的任務(wù),當(dāng)所有任務(wù)完成時(shí),返回保持任務(wù)狀態(tài)和結(jié)果的 Future 列表。返回列表的所有元素的 Future.isDone() 為 true。 throws InterruptedException; T invokeAny(Collec
18、tion? extends Callable tasks)/執(zhí)行給定的任務(wù),如果在給定的超時(shí)期滿前某個(gè)任務(wù)已成功完成(也就是未拋出異常),則返回其結(jié)果。一旦正?;虍惓7祷睾?,則取消尚未完成的任務(wù)。 throws InterruptedException, ExecutionException; T invokeAny(Collection? extends Callable tasks, long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;ExecutorS
19、ervice接口繼承自Executor接口,它提供了更豐富的實(shí)現(xiàn)多線程的方法,比如,ExecutorService提供了關(guān)閉自己的方法,以及可為跟蹤一個(gè)或多個(gè)異步任務(wù)執(zhí)行狀況而生成 Future 的方法。 可以調(diào)用ExecutorService的shutdown()方法來(lái)平滑地關(guān)閉 ExecutorService,調(diào)用該方法后,將導(dǎo)致ExecutorService停止接受任何新的任務(wù)且等待已經(jīng)提交的任務(wù)執(zhí)行完成(已經(jīng)提交的任務(wù)會(huì)分兩類:一類是已經(jīng)在執(zhí)行的,另一類是還沒(méi)有開始執(zhí)行的),當(dāng)所有已經(jīng)提交的任務(wù)執(zhí)行完畢后將會(huì)關(guān)閉ExecutorService。因此我們一般用該接口來(lái)實(shí)現(xiàn)和管理多線程。E
20、xecutorService的生命周期包括三種狀態(tài):運(yùn)行、關(guān)閉、終止。創(chuàng)建后便進(jìn)入運(yùn)行狀態(tài),當(dāng)調(diào)用了shutdown()方法時(shí),便進(jìn)入關(guān)閉狀態(tài),此時(shí)意味著ExecutorService不再接受新的任務(wù),但它還在執(zhí)行已經(jīng)提交了的任務(wù),當(dāng)素有已經(jīng)提交了的任務(wù)執(zhí)行完后,便到達(dá)終止?fàn)顟B(tài)。如果不調(diào)用shutdown()方法,ExecutorService會(huì)一直處在運(yùn)行狀態(tài),不斷接收新的任務(wù),執(zhí)行新的任務(wù),服務(wù)器端一般不需要關(guān)閉它,保持一直運(yùn)行即可。Executor執(zhí)行Runnable任務(wù) 一旦Runnable任務(wù)傳遞到execute()方法,該方法便會(huì)自動(dòng)在一個(gè)線程上執(zhí)行。下面是是Executor執(zhí)行R
21、unnable任務(wù)的示例代碼:public class TestCachedThreadPool public static void main(String args) ExecutorService executorService = Executors.newCachedThreadPool(); / ExecutorService executorService = Executors.newFixedThreadPool(5); / ExecutorService executorService = Executors.newSingleThreadExecutor(); for (
22、int i = 0; i 5; i+) executorService.execute(new TestRunnable(); System.out.println(* a + i + *); executorService.shutdown(); class TestRunnable implements Runnable public void run() System.out.println(Thread.currentThread().getName() + 線程被調(diào)用了。); 結(jié)果 Executor執(zhí)行Callable任務(wù) 在Java 5之后,任務(wù)分兩類:一類是實(shí)現(xiàn)了Runnable
23、接口的類,一類是實(shí)現(xiàn)了Callable接口的類。兩者都可以被ExecutorService執(zhí)行,但是Runnable任務(wù)沒(méi)有返回值,而Callable任務(wù)有返回值。并且Callable的call()方法只能通過(guò)ExecutorService的submit(Callable task) 方法來(lái)執(zhí)行,并且返回一個(gè) Future,是表示任務(wù)等待完成的 Future。下面給出一個(gè)Executor執(zhí)行Callable任務(wù)的示例代碼: public class CallableDemo public static void main(String args) ExecutorService executo
24、rService = Executors.newCachedThreadPool(); ListFuture resultList = new ArrayListFuture(); /創(chuàng)建10個(gè)任務(wù)并執(zhí)行 for (int i = 0; i 10; i+) /使用ExecutorService執(zhí)行Callable類型的任務(wù),并將結(jié)果保存在future變量中 Future future = executorService.submit(new TaskWithResult(i); /將任務(wù)執(zhí)行結(jié)果存儲(chǔ)到List中 resultList.add(future); /遍歷任務(wù)的結(jié)果 for (Fut
25、ure fs : resultList) try while(!fs.isDone);/Future返回如果沒(méi)有完成,則一直循環(huán)等待,直到Future返回完成 System.out.println(fs.get(); /打印各個(gè)線程(任務(wù))執(zhí)行的結(jié)果 catch(InterruptedException e) e.printStackTrace(); catch(ExecutionException e) e.printStackTrace(); finally /啟動(dòng)一次順序關(guān)閉,執(zhí)行以前提交的任務(wù),但不接受新任務(wù) executorService.shutdown(); class Task
26、WithResult implements Callable private int id; public TaskWithResult(int id) this.id = id; /* * 任務(wù)的具體過(guò)程,一旦任務(wù)傳給ExecutorService的submit方法, * 則該方法自動(dòng)在一個(gè)線程上執(zhí)行 */ public String call() throws Exception System.out.println(call()方法被自動(dòng)調(diào)用! + Thread.currentThread().getName(); /該返回結(jié)果將被Future的get方法得到 return call()方法被自動(dòng)調(diào)用,任務(wù)返回的結(jié)果是: + id + + Thread.currentThread().getName(); 某次執(zhí)行結(jié)果如下: 從結(jié)果中可以同樣可以看出,submit也是首先選擇空閑線程來(lái)執(zhí)行任務(wù),如果沒(méi)有,才會(huì)創(chuàng)建新的線程來(lái)執(zhí)行任務(wù)。另外,需要注意:如果Future的返回尚未完成,則get()方法會(huì)阻塞等待,直到Future完成返回,可以通過(guò)調(diào)用isDone()方法判斷Future是否完成了返回。自定義線程池 自定義線
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 中石化買賣石油合同范本
- 書刊供貨合同范本
- 廠房 設(shè)備維修合同范本
- 網(wǎng)上調(diào)查課題申報(bào)書
- 合同范本組成
- 保潔小區(qū)開荒合同范本
- 醫(yī)用銷售合同范本
- 員工借調(diào)合同范例
- 產(chǎn)品模特簽約合同范本
- 南寧雅閣購(gòu)車合同范本
- 重慶市屬事業(yè)單位招聘真題2024
- 新版第三類醫(yī)療器械分類目錄
- 多智能體機(jī)器人系統(tǒng)控制及其應(yīng)用課件全套第1-8章多智能體機(jī)器人系統(tǒng)-異構(gòu)多智能體系統(tǒng)的協(xié)同控制和最優(yōu)控制
- 弗洛姆異化理論
- AQL抽樣標(biāo)準(zhǔn)表xls2
- 碳納米管_ppt課件
- 【課件】第2課如何鑒賞美術(shù)作品課件-高中美術(shù)人教版(2019)美術(shù)鑒賞
- 人力資源部經(jīng)理崗位說(shuō)明書
- [康熙字典9畫五行屬金的字加解釋] 康熙字典五行屬金的字
- 液化氣罐定期檢驗(yàn)方案
- 關(guān)于老年癡呆癥及其智能陪護(hù)設(shè)備的調(diào)查報(bào)告
評(píng)論
0/150
提交評(píng)論