public class ThreadA {
public static void main(String[] args) {
ThreadB threadB = new ThreadB();
threadB.start();
synchronized (threadB) {
try {
threadB.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("the total is ====>"+threadB.total);
}
}
class ThreadB extends Thread
{
int total;
public void run(){
synchronized (this) {
for(int i =0; i<5;i++)
{
System.out.println("lets add===>"+i);
total+= i;
}
notify(); // line no.31
System.out.println("after notify but within lock");
}
System.out.println("after notify but outside lock");
}
}
output :
lets add===>0
lets add===>1
lets add===>2
lets add===>3
lets add===>4
after notify but within lock
the total is ====>10
after notify but outside lock
我的问题:控制不应该在第31行之后立即回到“主”线程。理想情况下不应该打印 - “允许添加===&gt; 4”后立即“总数是====&gt; 10”?
为什么它执行synchronized块中的所有语句而不管第31行中的notify()语句?
答案 0 :(得分:0)
最后几行的顺序总是不一样。它取决于线程的调度方式,并且根据您拥有的代码无法保证。你执行notify
wait
的那一刻结束了,所以任何线程都可以按任何顺序运行。但是after notify but within lock
在锁定范围内,所以即使主线程被执行锁定也无法做任何事情
答案 1 :(得分:0)
我的问题:控制不应该在第31行之后立即回到“主”线程。
你要求不可能的事。调用notify
的线程仍在同步块中。一旦另一个线程完成等待,它就会回到同步块中。所以你要求的是同时要求两个线程在同一个对象上的同步块中,这正是这些块禁止的。
synchronized (threadB) {
try {
threadB.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("the total is ====>"+threadB.total);
所以这段代码就是这样做的:
wait
。注意:
我们不能退出同步块,除非我们在同步块中;以及
在我们从wait
返回之前,我们无法退出已同步的块;从而
我们不能从wait
进入打印总数而不是在同步块中,因此当另一个线程保留在synchronized块中时我们不能这样做,否则将会有两个线程同步阻止。
现在看看这段代码:
notify(); // line no.31
System.out.println("after notify but within lock");
} // exit synchronized block
因此,任何通知另一个线程的线程在打印之前都不会保留其同步块。因此,通知的线程在打印之前不能退出其同步块。