我已经看到线程可以通过不同的方式进入阻塞状态。我很想知道线程处于阻塞状态后到底发生了什么。它如何回到运行状态。如果它被睡眠(时间)阻止,那么它会在毫秒之后移动到可运行队列。如果它在I / O操作上被阻塞,那么一旦完成它就会进入可运行队列。 它在等待对象锁时如何到达可运行队列。它是如何知道它等待的对象的锁定现在可用。有人还可以解释I / O上被阻塞线程如何工作的内部结构。 如果我对上述任何主题的理解不正确,请纠正我。
谢谢
答案 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未指定monitorenter
和monitorexit
应如何实现的具体细节。也就是说,它依赖于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源代码。它是公开的。