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();
}
}}
我无法理解代码流以及如何在上述程序中调用run方法。
当对象属于类ThreadB
时,为什么main()
的{{1}}线程能够同步对象ThreadA
。除了b
主题遇到wait()
时,执行情况如何转移到main()
中的run()
。
答案 0 :(得分:1)
为什么即使在ThreadB的run()能够执行之前,main()也会到达synchronized块。
您的程序有竞争条件。
在main()
调用b.start()
之后,有两个线程正在运行,未同步,并且它们竞争锁定(即同步)b
对象。没有办法预测哪个线程会先锁定它。
如果main()
线程首先锁定它,那么它将调用b.wait()
。这将暂时解锁b
对象,并允许其他线程运行。另一个线程将完成其工作,调用b.notify()
并退出synchronized
块。退出后,main()
主题就可以从wait()
调用返回。
如果第二个线程是第一个锁定b
对象,则行为将不同:它将完成其工作,调用notify()
并返回。但是notify()
调用在这种情况下不会执行任何操作,因为main()
线程将被阻止尝试进入synchronized
块。它不会在b.wait()
电话中等待,notify()
如果没有其他线程在等待,则不会做任何事情。
那么接下来会发生的情况是,当ThreadB
线程离开synchronized
块时,main()
线程将能够输入它并调用wait()
。该程序将在此时挂起,因为ThreadB
线程已完成其工作并已死亡。没有其他线程可以拨打notify()
。
当两个(或更多)线程竞相做某事时,我们将其称为竞争条件,并且程序的输出取决于首先到达哪个。
答案 1 :(得分:0)
除了main()线程遇到wait()时,执行如何转换为ThreadB中的run()。
在调用wait()
之前如果它将在下一步调用wait method
,则表示主线程当前持有对象b
的监视器。如果threadB想要执行 run()方法,它将被阻止等待主线程所持有的b
的{em> monitor
调用wait()
这意味着main thread
发布监视器,进入等待状态,并建议线程调度程序 re_dispatch。然后 ThreadB 可以获得监视器并制作东西。
<强>通知()强>
完成其工作后,threadB调用 notify()来唤醒正在等待此对象的监视器的单个线程,这里是主线程。 主线程将继续开展工作。