2011-01-25 63 views
4

我看到線程可能有不同的方式進入阻塞狀態。我很想知道線程處於阻塞狀態後究竟發生了什麼。它如何回到運行狀態。如果它被睡眠(時間)阻塞,那麼它會在毫秒後移動到可運行隊列。如果它在I/O操作上被阻塞,那麼一旦完成,它就進入可運行隊列。 它在等待對象鎖定時如何到達可運行隊列。它如何知道它所等待的對象上的鎖現在可用。有人可以解釋I/O上的阻塞線程是如何工作的。 請糾正我,如果我的上述任何主題的理解是不正確的..線程處於阻塞狀態的原因是由等待由JVM處理的對象鎖造成的

謝謝

回答

3

它是如何得到,當它正在等待的對象鎖定在可運行隊列?

如果該線程被阻塞在試圖輸入一個​​塊,該線程被自動標記爲可運行時另一個線程(持有鎖)通過從相同對象的​​塊離開釋放該鎖。

如果由於調用someObject.wait()而導致當前線程被阻塞,當另一個線程調用someObject.notify()時,線程將「釋放」。

在字節級,它看起來如下:

[load some object, obj, onto the operand stack] 
monitorenter // grab the lock 

// do stuff 

[load obj onto the operand stack again] 
monitorexit // release the lock 

如果別人已經擁有的obj鎖,線程將在monitorenter掛起,直到其他線程調用monitorexit

JLS未指定monitorentermonitorexit應該如何實現的具體細節。也就是說,它依賴於JVM/OS。

有關詳細信息,請參閱JLS Wait Sets and Notifications

0

在一個貼近代碼級別,它看起來是這樣的:

主題1:

Object mutex = new Object(); 
.... 
synchronized(mutex) { 
    //lock to mutex is acquired. 
    mutex.wait(); //lock to mutex is released. Thread is waiting for somebody to call notify(). 
    doSomething(); 
} 

線程2:

synchronized(Thread1.mutex) { 
    //acquires the lock on mutex. 
    //Can be done only after mutex.wait() is called from Thread1 
    // and the lock is released 
    Thread1.mutex.notify(); // notifies Thread1 that it can be resumed. 
} 

一般來說,你應該記住,主題.sleep()持有資源上的鎖,但Thread.wait()釋放鎖並可由其他線程通知。

0

AFAIK JVM使用本機線程。因此,OS和JVM都管理線程調度和上下文切換。

你可以看看實際的JVM源代碼。它是開放的。

+0

如果你明確提到太陽/神諭熱點JVM,你可能想澄清這一點。 – aioobe

+1

關於JVM源的SO帖子:http://stackoverflow.com/questions/2026093/is-jvm-open-source-code-if-not-how-can-i-get-code-of-jvm – 9dan

相關問題