参考下面的代码
public void acquire(){ synchronized(a){ print("acquire()"); try{ //Thread.sleep(5000); synchronized(this){ wait(5000); } print("I have awoken"); print("" + a); }catch(Exception e){ e.printStackTrace(); } } print("Leaving acquire()"); } public void modify(int n){ print("Entered in modfy"); synchronized(a){ try{ //Thread.sleep(5000); synchronized(this){ wait(5000); } this.a=n; print("new value" + a); }catch(Exception e){ e.printStackTrace(); } } }
和
final SynchoTest ttObj = new SynchoTest(); Thread A = new Thread(new Runnable(){ public void run() { ttObj.acquire(); } },"A"); Thread B = new Thread(new Runnable(){ public void run() { ttObj.modify(97); } },"B"); A.start(); B.start();
据我所知,wait(n)会暂停线程,直到调用notify()/ notifyAll()或指定的时间n结束为止。
但…
请告诉我为什么?还告诉我,如果我使用sleep(n)而不是wait(n),为什么在定位同步块上没有什么不同?
我的问题是关于关键字的各个位置上的wait(n)的各种结果。
@灰色
notify()或notifyAll()和wait()必须在您正在等待的对象的同步块中
向我解释了为什么我通过将同步块放置在各个位置来获取运行时异常。
现在请解释一下为什么
public void method(){ synchronized(a){ synchronized(this){ wait(n); } } }
工作正常。但
public synchronized void method(){ synchronized(a){ wait(n); } }
永远阻塞我的线程。
与定位同步关键字无关。由于您锁定了另一个对象并尝试等待另一个对象,因此您面临问题。好吧,@ Gray已经对此进行了解释,因此不再重复。
对于您的另一个问题,关于为什么两个线程都被阻塞;
线程A:锁定此[A:可运行] 线程A:锁定[A:可运行] 线程B:正在等待[A:可运行,B:已阻止] 线程A:释放该线程(表示等待)[A:定时等待,B:已阻止] 线程B:锁定此线程[A:定时等待,B:可运行] 线程B:等待已被线程A锁定的线程[A:定时等待,B:已阻止] 线程A:等待被线程B锁定的线程[A:已阻止,B:已阻止]
线程A:锁定此[A:可运行]
线程A:锁定[A:可运行]
线程B:正在等待[A:可运行,B:已阻止]
线程A:释放该线程(表示等待)[A:定时等待,B:已阻止]
线程B:锁定此线程[A:定时等待,B:可运行]
线程B:等待已被线程A锁定的线程[A:定时等待,B:已阻止]
线程A:等待被线程B锁定的线程[A:已阻止,B:已阻止]