日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

java線程池

 老匹夫 2014-01-23

java線程池

 

ExecutorService是線程池的一個(gè)服務(wù),可以隨時(shí)關(guān)閉線程池,是繼承Executor的。Executors是個(gè)工廠類,專門創(chuàng)建各種線程池。

Android常用的線程池有一下幾種,在Executors里面對(duì)應(yīng)的方法:

1. newFixedThreadPool

創(chuàng)建一個(gè)可重用固定線程數(shù)的線程池,以共享的無(wú)界隊(duì)列方式來(lái)運(yùn)行這些線程。在任意點(diǎn),在大多數(shù) nThreads 線程會(huì)處于處理任務(wù)的活動(dòng)狀態(tài)。如果在所有線程處于活動(dòng)狀態(tài)時(shí)提交附加任務(wù),則在有可用線程之前,附加任務(wù)將在隊(duì)列中等待。如果在關(guān)閉前的執(zhí)行期間由于失敗而導(dǎo)致任何線程終止,那么一個(gè)新線程將代替它執(zhí)行后續(xù)的任務(wù)(如果需要)。在某個(gè)線程被顯式地關(guān)閉之前,池中的線程將一直存在。 

-newFixedThreadPool與cacheThreadPool差不多,也是能reuse就用,但不能隨時(shí)建新的線程 

-其獨(dú)特之處:任意時(shí)間點(diǎn),最多只能有固定數(shù)目的活動(dòng)線程存在,此時(shí)如果有新的線程要建立,只能放在另外的隊(duì)列中等待,直到當(dāng)前的線程中某個(gè)線程終止直接被移出池子 

-和cacheThreadPool不同,F(xiàn)ixedThreadPool沒有IDLE機(jī)制(可能也有,但既然文檔沒提,肯定非常長(zhǎng),類似依賴上層的TCP或UDP IDLE機(jī)制之類的),所以FixedThreadPool多數(shù)針對(duì)一些很穩(wěn)定很固定的正規(guī)并發(fā)線程,多用于服務(wù)器 

-從方法的源代碼看,cache池和fixed 池調(diào)用的是同一個(gè)底層池,只不過(guò)參數(shù)不同: 

fixed池線程數(shù)固定,并且是0秒IDLE(無(wú)IDLE) 

cache池線程數(shù)支持0-Integer.MAX_VALUE(顯然完全沒考慮主機(jī)的資源承受能力),60秒IDLE  

  ExecutorService pool = Executors.newFixedThreadPool(2); 

  //創(chuàng)建實(shí)現(xiàn)了Runnable接口對(duì)象,Thread對(duì)象當(dāng)然也實(shí)現(xiàn)了Runnable接口 

  Thread t1 = new MyThread(); 

  Thread t2 = new MyThread(); 

  Thread t3 = new MyThread(); 

  Thread t4 = new MyThread(); 

  Thread t5 = new MyThread(); 

  //將線程放入池中進(jìn)行執(zhí)行 

  pool.execute(t1); 

  pool.execute(t2); 

  pool.execute(t3); 

  pool.execute(t4); 

  pool.execute(t5);

 

2. newCachedThreadPool

創(chuàng)建一個(gè)可根據(jù)需要?jiǎng)?chuàng)建新線程的線程池,但是在以前構(gòu)造的線程可用時(shí)將重用它們。對(duì)于執(zhí)行很多短期異步任務(wù)的程序而言,這些線程池通??商岣叱绦蛐阅?。調(diào)用 execute 將重用以前構(gòu)造的線程(如果線程可用)。如果現(xiàn)有線程沒有可用的,則創(chuàng)建一個(gè)新線程并添加到池中。終止并從緩存中移除那些已有 60 秒鐘未被使用的線程。因此,長(zhǎng)時(shí)間保持空閑的線程池不會(huì)使用任何資源。注意,可以使用 ThreadPoolExecutor 構(gòu)造方法創(chuàng)建具有類似屬性但細(xì)節(jié)不同(例如超時(shí)參數(shù))的線程池。

-緩存型池子,先查看池中有沒有以前建立的線程,如果有,就reuse.如果沒有,就建一個(gè)新的線程加入池中 

-緩存型池子通常用于執(zhí)行一些生存期很短的異步型任務(wù) 

因此在一些面向連接的daemon型SERVER中用得不多。 

-能reuse的線程,必須是timeout IDLE內(nèi)的池中線程,缺省timeout是60s,超過(guò)這個(gè)IDLE時(shí)長(zhǎng),線程實(shí)例將被終止及移出池。 

  注意,放入CachedThreadPool的線程不必?fù)?dān)心其結(jié)束,超過(guò)TIMEOUT不活動(dòng),其會(huì)自動(dòng)被終止。

 

3. newSingleThreadExecutor

創(chuàng)建一個(gè)使用單個(gè) worker 線程的 Executor,以無(wú)界隊(duì)列方式來(lái)運(yùn)行該線程。(注意,如果因?yàn)樵陉P(guān)閉前的執(zhí)行期間出現(xiàn)失敗而終止了此單個(gè)線程,那么如果需要,一個(gè)新線程將代替它執(zhí)行后續(xù)的任務(wù))。可保證順序地執(zhí)行各個(gè)任務(wù),并且在任意給定的時(shí)間不會(huì)有多個(gè)線程是活動(dòng)的。與其他等效的 newFixedThreadPool(1) 不同,可保證無(wú)需重新配置此方法所返回的執(zhí)行程序即可使用其他的線程。

-單例線程,任意時(shí)間池中只能有一個(gè)線程 

-用的是和cache池和fixed池相同的底層池,但線程數(shù)目是1-1,0秒IDLE(無(wú)IDLE)

 

4.newScheduledThreadPool 

-調(diào)度型線程池 

-這個(gè)池子里的線程可以按schedule依次delay執(zhí)行,或周期執(zhí)行

 

 

這三個(gè)方法都返回了一個(gè)ExecutorService類型的對(duì)象。實(shí)際上,ExecutorService是一個(gè)接口,它的submit()方法負(fù)責(zé)接收任務(wù)并交與線程池中的線程去運(yùn)行。submit()方法能夠接受Callable和Runnable兩種類型的對(duì)象。它們的用法和區(qū)別如下: 

Runnable接口:繼承Runnable接口的類要實(shí)現(xiàn)它的run()方法,并將執(zhí)行任務(wù)的代碼放入其中,run()方法沒有返回值。適合于只做某種操作,不關(guān)心運(yùn)行結(jié)果的情況。

Callable接口:繼承Callable接口的類要實(shí)現(xiàn)它的call()方法,并將執(zhí)行任務(wù)的代碼放入其中,call()將任務(wù)的執(zhí)行結(jié)果作為返回值。適合于執(zhí)行某種操作后,需要知道執(zhí)行結(jié)果的情況。

 

無(wú)論是接收Runnable型參數(shù),還是接收Callable型參數(shù)的submit()方法,都會(huì)返回一個(gè)Future(也是一個(gè)接口)類型的對(duì)象。該對(duì)象中包含了任務(wù)的執(zhí)行情況以及結(jié)果。調(diào)用Future的boolean isDone()方法可以獲知任務(wù)是否執(zhí)行完畢;調(diào)用Object get()方法可以獲得任務(wù)執(zhí)行后的返回結(jié)果,如果此時(shí)任務(wù)還沒有執(zhí)行完,get()方法會(huì)保持等待,直到相應(yīng)的任務(wù)執(zhí)行完畢后,才會(huì)將結(jié)果返回。 

 

我們用下面的一個(gè)例子來(lái)演示Java5.0中線程池的使用: 

[java] view plaincopy 

import java.util.concurrent.*;  

public class ExecutorTest {  

    public static void main(String[] args) throws InterruptedException,  

            ExecutionException {  

        ExecutorService es = Executors.newSingleThreadExecutor();  

        Future fr = es.submit(new RunnableTest());// 提交任務(wù)  

        Future fc = es.submit(new CallableTest());// 提交任務(wù)  

        // 取得返回值并輸出  

        System.out.println((String) fc.get());  

        // 檢查任務(wù)是否執(zhí)行完畢  

        if (fr.isDone()) {  

            System.out.println("執(zhí)行完畢-RunnableTest.run()");  

        } else {  

            System.out.println("未執(zhí)行完-RunnableTest.run()");  

        }  

        // 檢查任務(wù)是否執(zhí)行完畢  

        if (fc.isDone()) {  

            System.out.println("執(zhí)行完畢-CallableTest.run()");  

        } else {  

            System.out.println("未執(zhí)行完-CallableTest.run()");  

        }  

        // 停止線程池服務(wù)  

        es.shutdown();  

    }  

}  

class RunnableTest implements Runnable {  

    public void run() {  

        System.out.println("已經(jīng)執(zhí)行-RunnableTest.run()");  

    }  

}  

class CallableTest implements Callable {  

    public Object call() {  

        System.out.println("已經(jīng)執(zhí)行-CallableTest.call()");  

        return "返回值-CallableTest.call()";  

    }  

}  

 

運(yùn)行結(jié)果: 

已經(jīng)執(zhí)行-RunnableTest.run()

已經(jīng)執(zhí)行-CallableTest.call()

返回值-CallableTest.call()

執(zhí)行完畢-RunnableTest.run()

執(zhí)行完畢-CallableTest.run()

 

使用完線程池之后,需要調(diào)用它的shutdown()方法停止服務(wù),否則其中的所有線程都會(huì)保持運(yùn)行,程序不會(huì)退出。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多