Java 中 wait() 和 notifyAll() 的行为?
Behavior of wait() and notifyAll() in Java?
请注意,这不是实际情况。我根据我的实际实现创建了一个示例场景,以便于查看。我也已经得到了预期的输出。但是,我需要澄清一些关于 Java 中的 wait()
和 notifyAll()
方法的概念。 (在这里,这两个线程将在主线程中立即从 运行 方法开始。)因此,据我所知,由于线程 B 正在休眠,因为您可以在初始阶段看到 reamingCount 为 400。
所以线程 B 将调用它的 MUTEX.wait()
并继续睡眠直到其他线程调用 notify()
或 notifyAll()
,然后在 remainingCount 递减为 0 后,线程 A 将调用MUTEX.notifyAll();
唤醒线程 B 并 MUTEX.wait()
释放其已授予的锁,然后进入睡眠状态直到线程 B 通知它。
当我通过线程 A 调用 MUTEX.notifyAll()
时,线程 B 不会在线程 A 调用 MUTEX.wait()
之前唤醒并继续其任务吗?
我的意思是,你可以看到当线程 A 调用 MUTEX.notifyAll()
时,线程 B 将唤醒并再次检查 while 循环中的条件是真还是假。因此,由于 remainingCount 等于 0,线程 B 将退出 while 循环并在线程 A 调用 wait()
之前继续其任务。这种情况不会破坏wait()
的原则吗?据我所知线程B只有在线程A调用wait()
.
时才能继续执行
public class A implements Runnable{
public static volatile remainingCount =400;
private final Object MUTEX;//Both class A and B holds the same object mutex
private void methodA(){
synchronized(MUTEX){
while(remainingCount == 0){
MUTEX.notifyAll();
MUTEX.wait();
}
//Perform it's usual task.In here remaining count will decrement during the process.
}
@Override
public void run() {
while(true){
methodA();
}
}
}
}
public class B implements Runnable{
private final Object MUTEX;//Both class A and B holds the same object mutex
private void methodB(){
synchronized(MUTEX){
while (A.remainingCount != 0) {
try {
MUTEX.wait();
} catch (InterruptedException ex) {
Logger.getLogger(InkServiceImpl.class.getName()).log(Level.SEVERE, null, ex);
}
}
//incrementing the A.remainingCount
MUTEX.notifyAll();
}
@Override
public void run() {
while(true){
methodB();
}
}
}
当持有锁的线程在锁定的对象上调用 wait()
时,线程被添加到对象的等待集中并释放锁。
当一个持有锁的线程调用notify()
,并且等待集不为空时,选择并移除等待集中的一个线程。同样,调用 notifyAll()
会从等待集中删除所有线程。
注意:也可以通过调用 thread.interrupt()
.
从等待集中删除线程
当一个线程从等待集中移除并开始运行时,第一步是重新获取锁。这发生在 wait()
.
的 return 之前
这不会发生,直到调用 notify()
或 notifyAll()
的线程通过调用 wait()
或退出同步块释放锁。
因此,虽然您的线程 B 已启用 运行,但它实际上不会 return 从 wait()
直到线程 A 通过调用 MUTEX.wait()
释放锁.同样,线程 A 在 B 调用 MUTEX.notifyAll()
时启用 运行,但在线程 B 退出 synchronized(MUTEX)
块之前不会从 wait()
return。
请注意,这不是实际情况。我根据我的实际实现创建了一个示例场景,以便于查看。我也已经得到了预期的输出。但是,我需要澄清一些关于 Java 中的 wait()
和 notifyAll()
方法的概念。 (在这里,这两个线程将在主线程中立即从 运行 方法开始。)因此,据我所知,由于线程 B 正在休眠,因为您可以在初始阶段看到 reamingCount 为 400。
所以线程 B 将调用它的 MUTEX.wait()
并继续睡眠直到其他线程调用 notify()
或 notifyAll()
,然后在 remainingCount 递减为 0 后,线程 A 将调用MUTEX.notifyAll();
唤醒线程 B 并 MUTEX.wait()
释放其已授予的锁,然后进入睡眠状态直到线程 B 通知它。
当我通过线程 A 调用 MUTEX.notifyAll()
时,线程 B 不会在线程 A 调用 MUTEX.wait()
之前唤醒并继续其任务吗?
我的意思是,你可以看到当线程 A 调用 MUTEX.notifyAll()
时,线程 B 将唤醒并再次检查 while 循环中的条件是真还是假。因此,由于 remainingCount 等于 0,线程 B 将退出 while 循环并在线程 A 调用 wait()
之前继续其任务。这种情况不会破坏wait()
的原则吗?据我所知线程B只有在线程A调用wait()
.
public class A implements Runnable{
public static volatile remainingCount =400;
private final Object MUTEX;//Both class A and B holds the same object mutex
private void methodA(){
synchronized(MUTEX){
while(remainingCount == 0){
MUTEX.notifyAll();
MUTEX.wait();
}
//Perform it's usual task.In here remaining count will decrement during the process.
}
@Override
public void run() {
while(true){
methodA();
}
}
}
}
public class B implements Runnable{
private final Object MUTEX;//Both class A and B holds the same object mutex
private void methodB(){
synchronized(MUTEX){
while (A.remainingCount != 0) {
try {
MUTEX.wait();
} catch (InterruptedException ex) {
Logger.getLogger(InkServiceImpl.class.getName()).log(Level.SEVERE, null, ex);
}
}
//incrementing the A.remainingCount
MUTEX.notifyAll();
}
@Override
public void run() {
while(true){
methodB();
}
}
}
当持有锁的线程在锁定的对象上调用 wait()
时,线程被添加到对象的等待集中并释放锁。
当一个持有锁的线程调用notify()
,并且等待集不为空时,选择并移除等待集中的一个线程。同样,调用 notifyAll()
会从等待集中删除所有线程。
注意:也可以通过调用 thread.interrupt()
.
当一个线程从等待集中移除并开始运行时,第一步是重新获取锁。这发生在 wait()
.
这不会发生,直到调用 notify()
或 notifyAll()
的线程通过调用 wait()
或退出同步块释放锁。
因此,虽然您的线程 B 已启用 运行,但它实际上不会 return 从 wait()
直到线程 A 通过调用 MUTEX.wait()
释放锁.同样,线程 A 在 B 调用 MUTEX.notifyAll()
时启用 运行,但在线程 B 退出 synchronized(MUTEX)
块之前不会从 wait()
return。