我看到線程可能有不同的方式進入阻塞狀態。我很想知道線程處於阻塞狀態後究竟發生了什麼。它如何回到運行狀態。如果它被睡眠(時間)阻塞,那麼它會在毫秒後移動到可運行隊列。如果它在I/O操作上被阻塞,那麼一旦完成,它就進入可運行隊列。 它在等待對象鎖定時如何到達可運行隊列。它如何知道它所等待的對象上的鎖現在可用。有人可以解釋I/O上的阻塞線程是如何工作的。 請糾正我,如果我的上述任何主題的理解是不正確的..線程處於阻塞狀態的原因是由等待由JVM處理的對象鎖造成的
謝謝
我看到線程可能有不同的方式進入阻塞狀態。我很想知道線程處於阻塞狀態後究竟發生了什麼。它如何回到運行狀態。如果它被睡眠(時間)阻塞,那麼它會在毫秒後移動到可運行隊列。如果它在I/O操作上被阻塞,那麼一旦完成,它就進入可運行隊列。 它在等待對象鎖定時如何到達可運行隊列。它如何知道它所等待的對象上的鎖現在可用。有人可以解釋I/O上的阻塞線程是如何工作的。 請糾正我,如果我的上述任何主題的理解是不正確的..線程處於阻塞狀態的原因是由等待由JVM處理的對象鎖造成的
謝謝
它是如何得到,當它正在等待的對象鎖定在可運行隊列?
如果該線程被阻塞在試圖輸入一個塊,該線程被自動標記爲可運行時另一個線程(持有鎖)通過從相同對象的塊離開釋放該鎖。
如果由於調用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未指定monitorenter
和monitorexit
應該如何實現的具體細節。也就是說,它依賴於JVM/OS。
有關詳細信息,請參閱JLS Wait Sets and Notifications。
在一個貼近代碼級別,它看起來是這樣的:
主題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()釋放鎖並可由其他線程通知。
AFAIK JVM使用本機線程。因此,OS和JVM都管理線程調度和上下文切換。
你可以看看實際的JVM源代碼。它是開放的。
如果你明確提到太陽/神諭熱點JVM,你可能想澄清這一點。 – aioobe
關於JVM源的SO帖子:http://stackoverflow.com/questions/2026093/is-jvm-open-source-code-if-not-how-can-i-get-code-of-jvm – 9dan