Как поток в заблокированном состоянии вызван ожиданием блокировки объектов, обработанной JVM - PullRequest
4 голосов
/ 25 января 2011

Я видел, что существуют разные способы, которыми поток может перейти в заблокированное состояние.Мне интересно знать, что именно происходит после того, как поток находится в заблокированном состоянии.Как это вернуться в рабочее состояние.Если он заблокирован сном (время), то он перемещается в работоспособную очередь через миллисекунды.Если он заблокирован во время операции ввода / вывода, он попадает в рабочую очередь, как только это будет сделано.как он попадает в очередь выполнения, когда ожидает блокировки объектов.откуда он знает, что блокировка объекта теперь его ждет.Может ли кто-нибудь также объяснить внутреннее устройство того, как работает блокированный поток в операциях ввода-вывода.Пожалуйста, поправьте меня, если мое понимание какой-либо из вышеперечисленных тем не верно ..

Спасибо

Ответы [ 3 ]

3 голосов
/ 25 января 2011

Как он попадает в рабочую очередь, когда ожидает блокировки объектов?

Если поток заблокирован из-за попытки войти в блок synchronized, поток автоматически помечается как работоспособный, когда другой поток (удерживающий блокировку) снимает блокировку, выходя из блока synchronized того же объекта .

Если текущий поток заблокирован из-за вызова 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.

Точные подробности реализации monitorenter и monitorexit не определяются JLS. То есть это зависит от JVM / OS.

Подробнее см. Наборы ожидания JLS и уведомления .

0 голосов
/ 25 января 2011

AFAIK JVM использует собственные темы.Так что именно ОС, а не JVM, управляет расписанием потоков и переключением контекста.

Вы можете посмотреть фактический исходный код JVM.Открыто.

0 голосов
/ 25 января 2011

На уровне, близком к коду, это выглядит так:

Тема 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.
}

В общем, вам следуетимейте в виду, что Thread.sleep () удерживает блокировку ресурсов, но Thread.wait () снимает блокировку и может быть уведомлен другими потоками.

...