如何通过等待JVM处理的对象锁来导致线程处于阻塞状态

时间:2011-01-25 14:10:47

标签: java multithreading synchronized blocked

我已经看到线程可以通过不同的方式进入阻塞状态。我很想知道线程处于阻塞状态后到底发生了什么。它如何回到运行状态。如果它被睡眠(时间)阻止,那么它会在毫秒之后移动到可运行队列。如果它在I / O操作上被阻塞,那么一旦完成它就会进入可运行队列。 它在等待对象锁时如何到达可运行队列。它是如何知道它等待的对象的锁定现在可用。有人还可以解释I / O上被阻塞线程如何工作的内部结构。 如果我对上述任何主题的理解不正确,请纠正我。

谢谢

3 个答案:

答案 0 :(得分:3)

  

在等待对象锁定时如何到达可运行队列?

如果由于尝试输入synchronized块而阻塞了线程,当另一个线程(持有锁)通过退出synchronized块释放锁时,线程会自动标记为runnable相同的对象。

如果当前线程由于调用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

答案 1 :(得分: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.
}

一般来说,你应该记住Thread.sleep()持有对资源的锁定,但是Thread.wait()会释放锁定,并且可以被其他线程通知。

答案 2 :(得分:0)

AFAIK JVM使用本机线程。因此,操作系统不是JVM来管理线程调度和上下文切换。

您可以查看实际的JVM源代码。它是公开的。