標籤:線程阻塞 需要 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()