繁体   English   中英

确保在线程中的notify()之前调用wait(),这可能吗?

[英]Assuring wait() is called before notify() in threading, is it possible?

当我遇到一个使用wait / notify方法的示例时,我正在看Kathy Sierra的书中的Threading一章:

 class ThreadA {
 public static void main(String [] args) {
 ThreadB b = new ThreadB();
 b.start();

 synchronized(b) {
 try {
    System.out.println("Waiting for b to complete...");
    b.wait();
     } catch (InterruptedException e) {}
 System.out.println("Total is: " + b.total);
 }
}
}

class ThreadB extends Thread { 
 int total;
 public void run() {
  synchronized(this) {
   for(int i=0;i<100;i++) {
   total += i;
   }
  notify();
 }
}
}

运行代码始终会产生相同的输出:

等待b完成...总计为:4950

我通过添加以下内容修改了ThreadB中run()的同步块:

System.out.println("ThreadB is executed"); 

问题是:为什么我不断

“正在等待b完成...”

之前

“执行ThreadB”

线程b是否有可能在主线程之前执行?

线程b是否有可能在主线程之前执行?

是的,一点没错。

通常wait会伴随一些谓词,以防止此类问题。

例如,ThreadB可以有一个变量,表示已完成。 您可以检查合计是否不为0。

synchronized (b) {
    try {
        System.out.println("Waiting for b to complete...");
        while (b.total == 0) {
            b.wait();
        }
    } catch (InterruptedException e) {
    }
    System.out.println("Total is: " + b.total);
}

相对于ThreadB中的写入,这会在total的读取上创建一个事前发生的关系。

线程b是否有可能在主线程之前执行?

是的,存在这种可能性,尽管对于狭窄的种族(如本段代码中的种族)而言,这种可能性很小。

该代码在获取b的监视器(同步块)之前调用b.start() )。 在该窗口期间,主线程有可能被抢占,而线程B将首先运行并获取该监视器。

在这种情况下,该程序将挂起,因为主线程将永远wait()因为它错过了线程B的notify()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM