java中的interrupt(),InterruptException和wait(),sleep()

來源:互聯網
上載者:User

標籤:線程阻塞   需要   thread   err   class   dna   通過   pex   問題   

    標題中的幾個概念大概設計到線程同步以及線程阻塞這兩個概念。線程同步,就是同一時刻,只有一個線程能執行指定的代碼;另外一個線程阻塞就是當前線程暫時停在某個位置,等待某個條件成立之後再繼續往下面執行。

    線程同步就是,是為了控制多線程工作存在的並發造成共用資源競爭的問題。java中可以通過加鎖(monitor)的方式來控制,其實就是兩個關鍵字,一個是synchronized,另外一個是lock,關於這兩個的區別,請自行google。其中wait方法就必須擷取某個對象的monitor之後,才允許執行,否則會跑出monitor status不正確的異常。wait()和join()方法是屬於Object的執行個體方法。wait()方法必須放在同步代碼塊之內(如下),即是表示獲得了某個對象的monitor(鎖)之後,才允許執行該對象的wait()方法;執行了wait()方法之後,當前線程會處於阻塞狀態,這時候當前線程會釋放進來的時候擷取的指定對象的monitor(鎖),同時讓出cpu,不在參與cpu的競爭,等待其他線程執行指定對象的notify()或者notifyAll()方法來將其喚醒,以繼續執行下去(被喚醒之後,也要先擷取指定對象的鎖才會進來,因為同步塊進來之前必須是擷取了指定對象的monitor,同時,不是從新執行,獲得monitor之後,是從之前wait()那裡開始繼續網下面執行,因為之前在這裡阻塞了,cpu相關的寄存在會記住之前阻塞的位置的)。    
public class Service {    public void testMethod(Object lock) {        try {            synchronized (lock) {                System.out.println("begin wait() ThreadName=" + Thread.currentThread().getName());                lock.wait();                if (Thread.currentThread().getName().equals("Thread-1")) {                    Thread.sleep(50000);                }                System.out.println("end wait() ThreadName=" + Thread.currentThread().getName());            }        } catch (InterruptedException e) {            e.printStackTrace();        }    }    public void synNotifyMethod(Object lock) {        synchronized (lock) {            System.out.println("begin notify() ThreadName=" + Thread.currentThread().getName());            lock.notifyAll();            System.out.println("end notify() ThreadName=" + Thread.currentThread().getName());        }    }}

 

    至於interrupt()方法和InterruptException異常,是java專門用來處理線程阻塞的。線程阻塞,就表示要等待一段時間。如果需要等待的時間比較長,正常還沒結束之前想中斷某個線程的阻塞狀態怎麼辦?這就是靠interrupt()方法來解決了。如果因為一些特殊的原因,想提前中斷一些阻塞的線程,以讓他們提前解除阻塞狀態,然後繼續執行下去。只需要在其他線程調用指定線程的interrupt()方法即可(interrupt()方法是線程執行個體方法),這時候原來阻塞的對應的線程就會拋出InterruptException異常,通過catch捕獲異常就可以繼續往下面執行了。比如線程方法sleep()和Object的執行個體方法wait(),都會導致當前線程阻塞,這時候就可以通過interrupt()方法來提前退出阻塞狀態。    為什麼Interrupt()方法可以提前中斷阻塞呢?其實是因為每個線程都會有一個中斷狀態位,暫且叫做interruptStatus吧。當前執行sleep()和wait()這些方法的時候,當前線程會把該interrruptStatus狀態位設定為true,以標識當前線程為阻塞狀態。當調用該線程的Interrupt()方法的話,就會重設interruptStatus狀態為為false。而sleep()和wait()方法內部會不斷地輪詢檢查InterruptStatus狀態值,如果某一時刻變為false的時候,當前線程就會中斷阻塞狀態,通過拋出InterrupException的方式來中斷阻塞狀態,然後繼續執行下去。    至於wait()方法和notify()的關係,通過另外一篇文章來講述吧。



來自為知筆記(Wiz)



java中的interrupt(),InterruptException和wait(),sleep()

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.