<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    大鳥的學(xué)習(xí)樂園
    路漫漫其修遠(yuǎn)兮,吾將上下而求索
    posts - 26,comments - 27,trackbacks - 0
     我們都知道,在JDK1.5之前,Java中要進(jìn)行業(yè)務(wù)并發(fā)時,通常需要有程序員獨立完成代碼實現(xiàn),當(dāng)然也有一些開源的框架提供了這些功能,但是這些依然沒有JDK自帶的功能使用起來方便。而當(dāng)針對高質(zhì)量Java多線程并發(fā)程序設(shè)計時,為防止死蹦等現(xiàn)象的出現(xiàn),比如使用java之前的wait()、notify()和synchronized等,每每需要考慮性能、死鎖、公平性、資源管理以及如何避免線程安全性方面帶來的危害等諸多因素,往往會采用一些較為復(fù)雜的安全策略,加重了程序員的開發(fā)負(fù)擔(dān).萬幸的是,在JDK1.5出現(xiàn)之后,Sun大神(Doug Lea)終于為我們這些可憐的小程序員推出了java.util.concurrent工具包以簡化并發(fā)完成。開發(fā)者們借助于此,將有效的減少競爭條件(race conditions)和死鎖線程。concurrent包很好的解決了這些問題,為我們提供了更實用的并發(fā)程序模型。


    Executor                 :具體Runnable任務(wù)的執(zhí)行者。
    ExecutorService          :一個線程池管理者,其實現(xiàn)類有多種,我會介紹一部分。我們能把Runnable,Callable提交到池中讓其調(diào)度。
    Semaphore                :一個計數(shù)信號量
    ReentrantLock            :一個可重入的互斥鎖定 Lock,功能類似synchronized,但要強(qiáng)大的多。
    Future                   :是與Runnable,Callable進(jìn)行交互的接口,比如一個線程執(zhí)行結(jié)束后取返回的結(jié)果等等,還提供了cancel終止線程。
    BlockingQueue            :阻塞隊列。
    CompletionService        : ExecutorService的擴(kuò)展,可以獲得線程執(zhí)行結(jié)果的
    CountDownLatch           :一個同步輔助類,在完成一組正在其他線程中執(zhí)行的操作之前,它允許一個或多個線程一直等待。
    CyclicBarrier            :一個同步輔助類,它允許一組線程互相等待,直到到達(dá)某個公共屏障點
    Future                   :Future 表示異步計算的結(jié)果。
    ScheduledExecutorService :一個 ExecutorService,可安排在給定的延遲后運行或定期執(zhí)行的命令。

    接下來逐一介紹

    Executors主要方法說明
    newFixedThreadPool固定大小線程池)
    創(chuàng)建一個可重用固定線程集合的線程池,以共享的無界隊列方式來運行這些線程(只有要請求的過來,就會在一個隊列里等待執(zhí)行)。如果在關(guān)閉前的執(zhí)行期間由于失敗而導(dǎo)致任何線程終止,那么一個新線程將代替它執(zhí)行后續(xù)的任務(wù)(如果需要)。

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

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

    這些方法返回的都是ExecutorService對象,這個對象可以理解為就是一個線程池。
    這個線程池的功能還是比較完善的。可以提交任務(wù)submit()可以結(jié)束線程池shutdown()。

    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;

    public class MyExecutor extends Thread {
    private int index;
    public MyExecutor(int i){
       this.index=i;
    }
    public void run(){
       try{
        System.out.println("["+this.index+"] start....");
        Thread.sleep((int)(Math.random()*1000));
        System.out.println("["+this.index+"] end.");
       }
       catch(Exception e){
        e.printStackTrace();
       }
    }

    public static void main(String args[]){
       ExecutorService service=Executors.newFixedThreadPool(4);
       for(int i=0;i<10;i++){
        service.execute(new MyExecutor(i));
        //service.submit(new MyExecutor(i));
       }
       System.out.println("submit finish");
       service.shutdown();
    }
    }

    雖然打印了一些信息,但是看的不是非常清晰,這個線程池是如何工作的,我們來將休眠的時間調(diào)長10倍。
    Thread.sleep((int)(Math.random()*10000));

    再來看,會清楚看到只能執(zhí)行4個線程。當(dāng)執(zhí)行完一個線程后,才會又執(zhí)行一個新的線程,也就是說,我們將所有的線程提交后,線程池會等待執(zhí)行完最后shutdown。我們也會發(fā)現(xiàn),提交的線程被放到一個“無界隊列里”。這是一個有序隊列(BlockingQueue,這個下面會說到)。

    另外它使用了Executors的靜態(tài)函數(shù)生成一個固定的線程池,顧名思義,線程池的線程是不會釋放的,即使它是Idle。
    這就會產(chǎn)生性能問題,比如如果線程池的大小為200,當(dāng)全部使用完畢后,所有的線程會繼續(xù)留在池中,相應(yīng)的內(nèi)存和線程切換(while(true)+sleep循環(huán))都會增加。
    如果要避免這個問題,就必須直接使用ThreadPoolExecutor()來構(gòu)造。可以像通用的線程池一樣設(shè)置“最大線程數(shù)”、“最小線程數(shù)”和“空閑線程keepAlive的時間”。


    這個就是線程池基本用法。

    Semaphore
    一個計數(shù)信號量。從概念上講,信號量維護(hù)了一個許可集合。如有必要,在許可可用前會阻塞每一個 acquire(),然后再獲取該許可。每個 release() 添加一個許可,從而可能釋放一個正在阻塞的獲取者。但是,不使用實際的許可對象,Semaphore 只對可用許可的號碼進(jìn)行計數(shù),并采取相應(yīng)的行動。

    Semaphore 通常用于限制可以訪問某些資源(物理或邏輯的)的線程數(shù)目。例如,下面的類使用信號量控制對內(nèi)容池的訪問:

    這里是一個實際的情況,大家排隊上廁所,廁所只有兩個位置,來了10個人需要排隊。

    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Semaphore;

    public class MySemaphore extends Thread {
    Semaphore position;
    private int id;
    public MySemaphore(int i,Semaphore s){
       this.id=i;
       this.position=s;
    }

    public void run(){
       try{
        if(position.availablePermits()>0){
         System.out.println("顧客["+this.id+"]進(jìn)入廁所,有空位");
        }
        else{
         System.out.println("顧客["+this.id+"]進(jìn)入廁所,沒空位,排隊");
        }
        position.acquire();
        System.out.println("顧客["+this.id+"]獲得坑位");
        Thread.sleep((int)(Math.random()*1000));
        System.out.println("顧客["+this.id+"]使用完畢");
        position.release();
       }
       catch(Exception e){
        e.printStackTrace();
       }
    }
    public static void main(String args[]){
       ExecutorService list=Executors.newCachedThreadPool();
       Semaphore position=new Semaphore(2);
       for(int i=0;i<10;i++){
        list.submit(new MySemaphore(i+1,position));
       }
       list.shutdown();
       position.acquireUninterruptibly(2);
       System.out.println("使用完畢,需要清掃了");
       position.release(2);
    }
    }

     

    ReentrantLock
    一個可重入的互斥鎖定 Lock,它具有與使用 synchronized 方法和語句所訪問的隱式監(jiān)視器鎖定相同的一些基本行為和語義,但功能更強(qiáng)大。

    ReentrantLock 將由最近成功獲得鎖定,并且還沒有釋放該鎖定的線程所擁有。當(dāng)鎖定沒有被另一個線程所擁有時,調(diào)用 lock 的線程將成功獲取該鎖定并返回。如果當(dāng)前線程已經(jīng)擁有該鎖定,此方法將立即返回。可以使用 isHeldByCurrentThread() 和 getHoldCount() 方法來檢查此情況是否發(fā)生。

    此類的構(gòu)造方法接受一個可選的公平參數(shù)。
    當(dāng)設(shè)置為 true時,在多個線程的爭用下,這些鎖定傾向于將訪問權(quán)授予等待時間最長的線程。否則此鎖定將無法保證任何特定訪問順序。
    與采用默認(rèn)設(shè)置(使用不公平鎖定)相比,使用公平鎖定的程序在許多線程訪問時表現(xiàn)為很低的總體吞吐量(即速度很慢,常常極其慢),但是在獲得鎖定和保證鎖定分配的均衡性時差異較小。不過要注意的是,公平鎖定不能保證線程調(diào)度的公平性。因此,使用公平鎖定的眾多線程中的一員可能獲得多倍的成功機(jī)會,這種情況發(fā)生在其他活動線程沒有被處理并且目前并未持有鎖定時。還要注意的是,未定時的 tryLock 方法并沒有使用公平設(shè)置。因為即使其他線程正在等待,只要該鎖定是可用的,此方法就可以獲得成功。

    建議總是 立即實踐,使用 try 塊來調(diào)用 lock,在之前/之后的構(gòu)造中,最典型的代碼如下:
    class X {
       private final ReentrantLock lock = new ReentrantLock();
       // ...

       public void m() {
         lock.lock(); // block until condition holds
         try {
           // ... method body
         } finally {
           lock.unlock()
         }
       }
    }

    我的例子:
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.locks.ReentrantLock;

    public class MyReentrantLock extends Thread{
    TestReentrantLock lock;
    private int id;
    public MyReentrantLock(int i,TestReentrantLock test){
       this.id=i;
       this.lock=test;
    }

    public void run(){
       lock.print(id);
    }

    public static void main(String args[]){
       ExecutorService service=Executors.newCachedThreadPool();
       TestReentrantLock lock=new TestReentrantLock();
       for(int i=0;i<10;i++){
        service.submit(new MyReentrantLock(i,lock));
       }
       service.shutdown();
    }
    }
    class TestReentrantLock{
    private ReentrantLock lock=new ReentrantLock();
    public void print(int str){
       try{
        lock.lock();
        System.out.println(str+"獲得");
        Thread.sleep((int)(Math.random()*1000));
       }
       catch(Exception e){
        e.printStackTrace();
       }
       finally{
        System.out.println(str+"釋放");
        lock.unlock();
       }
    }
    }

    posted on 2009-09-14 17:06 大鳥 閱讀(514) 評論(0)  編輯  收藏 所屬分類: JAVA
    主站蜘蛛池模板: 国产精品亚洲а∨天堂2021| 亚洲综合无码无在线观看| 人体大胆做受免费视频| 又大又硬又爽免费视频| 国产成人亚洲综合a∨| 日韩毛片免费在线观看| 亚洲精品无码永久在线观看男男 | 亚洲人成网站色7799| 最近高清国语中文在线观看免费| 国产成人精品日本亚洲专| 国产免费AV片在线播放唯爱网| 亚洲国产精品专区| 成人免费看片又大又黄| 噜噜综合亚洲AV中文无码| 亚洲福利精品电影在线观看| 两个人www免费高清视频| 亚洲v高清理论电影| 亚洲精品视频免费看| 亚洲久悠悠色悠在线播放| 国产精品免费一级在线观看| 日韩一级片免费观看| 亚洲成A∨人片在线观看不卡| 久久九九AV免费精品| 麻豆狠色伊人亚洲综合网站| 免费一级肉体全黄毛片| 日韩精品无码免费专区网站| 亚洲白色白色在线播放| 国产免费人成在线视频| 日韩av无码免费播放| 91亚洲国产成人久久精品| 国产免费69成人精品视频| 免费毛片在线看不用播放器| 亚洲一区二区三区免费观看| 亚洲A丁香五香天堂网| 久9久9精品免费观看| 亚洲乱亚洲乱妇无码| 国产av无码专区亚洲av桃花庵| 国产在线观看片a免费观看| 成人特级毛片69免费观看| 亚洲人成网站日本片| 亚洲情侣偷拍精品|