Kev*_*vin 5 java concurrency multithreading
Java 线程可以由以下任一方式持有:
上述两种场景在Java线程状态方面有什么区别呢?
考虑下面的简单代码:
synchronized(object) {
object.wait();
System.out.println("Completed.");
}
Run Code Online (Sandbox Code Playgroud)
如果两个线程(比如 ThreadA 和 ThreadB)都被 wait() 方法持有。例如,当另一个线程调用notifyAll()时,ThreadA将从等待中恢复并获得对象上的锁并继续。ThreadB 也会复活,但无法获取对象的锁,并且会一直保持到 ThreadA 退出同步块为止。然后ThreadB获得锁并继续。
结果将打印两个“Completed”。
在这个例子中,肯定有一个时刻,ThreadB从“被wait()持有”变成“因为无法获得对象锁而被持有”。
我想知道它在 Java 内部是如何工作的。请帮忙。
object.wait()处于状态和等待监视器锁的区别在于object,处于object.wait()状态的线程释放其持有的所有监视器object,并且它会与系统中的所有线程竞争重新获取监视器。这形成了wait()一种特殊的状态。
因此,在您的情况下,当A和B(线程 A 和线程 B)处于等待状态时,它们没有同步监视器object,它们都已暂停执行,直到其他线程调用object.notify()或object.notifyAll()。当 被notifyAll()调用时,JVM 会唤醒处于状态的所有线程(在本例中A为 和B)object.wait(),并且它们竞争获取当前块的监视器synchronized。如果notify()调用,则 JVM 随机选取 A 或 B。
这里需要注意的是,JVM 不会通知任何特定线程,这就是为什么每个等待线程都必须在循环中等待while(notify_condition_for_me),以验证等待条件是否已满足,否则必须object.wait()再次进入该状态。
所以正确的代码应该是
synchronized(object) {
while(myResourceArrived) {//like URL data, JDBC data or something
object.wait();
}
System.out.println("Completed.");
}
Run Code Online (Sandbox Code Playgroud)
当A和B处于object.wait()状态时,它们已经释放了之前持有的所有监视器object,因此在块外等待的任何其他线程synchronized将能够通过获取已释放的监视器立即进入块object。
| 归档时间: |
|
| 查看次数: |
785 次 |
| 最近记录: |