public 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){
e.printStackTrace();
}
System.out.println("Total is: " + b.total);
}
}
}
class ThreadB extends Thread{
int total;
@Override
public void run(){
synchronized(this){
for(int i=0; i<100 ; i++){
total += i;
}
notify();
}
}
}
在上面的示例中,对象b
已同步。 b
在主线程输出其总值之前完成计算。
输出:
Waiting for b to complete...
Total is: 4950
如果main
线程首先获得b
的锁定,则main
线程将执行synchronized(b)
块。请b.wait()
暂停线程b
(线程b
还没有运行)?如果是,该代码如何产生结果?
如果线程b
首先获得内在锁定,那么notify()
的结果是什么?
答案 0 :(得分:3)
当您使用notify / wait时,您应该根据状态更改执行此操作。如果你不这样做,你可以解决一些问题。
如果在没有线程等待时通知(),则通知将丢失。稍后等待(等待)可能会永远等待。
如果你等待(),它可以虚假地唤醒,即它并不意味着有通知。
解决方案是:
不使用通知/等待,因为它在10年前被很大程度上取代了 并发库
让notify()线程更改字段/状态并拥有wait()线程 在循环中检查这个。
正如James Large所说,wait()ing是不公平的,因为无法保证第一个等待的线程将被通知下一个。
此外,如果不保持相同的同步锁定并且期望它始终正常运行,则无法更改状态。
答案 1 :(得分:2)
将
b.wait()
暂停线程b(线程b尚未运行)?如果是的话,如何 这段代码能产生结果吗?
不,这是synchronized(this)
(其中this
引用与b
相同的对象)将阻止另一个线程。一旦b.wait
被调用,b
引用的对象上的监视器被释放,主线程进入休眠状态,另一个线程获取监视器,进入synchronized
块。
如果线程b首先获得内部锁定,那么结果是什么
notify()
?
b
/ this
没有线程等待,所以notify
基本上什么都不做。当你的另一个线程释放监视器时,你的主线程将获取它并调用wait
,永远等待,因为notify
没有别的东西。