[b]认识object.wait()方法:[/b]
导致当前线程等待,直到该对象的notify或notifyall被执行。换句话说,这个方法行为效果完全与简单调用wait(0)一样。当前线程必须拥有对象监视器。线程释放对象监视器的所有权,等待直到另一个线程通过调用notify或notifyall来通知等待对象监视器的线程们并唤醒。然后,当前线程等待重新获取对象监视器并继续执行。因为在一个参数的版本中,中断与伪唤醒是可能的,这个方法应该通常在一个循环中使用:
synchronized (obj) {
while (<condition does not hold>)
obj.wait();
... // perform action appropriate to condition
}
该方法必须同步执行的,否则会抛出illegalmonitorstateexception。
[b]认识object.wait(long)方法:[/b]
基本功能与object.wait()相同,只是在指定时间间隔后,当前线程自动唤醒,并与其它线程竞争对象监视器,在获取对象监视器后,当前线程继续向前执行。
[b]认识object.notify方法:[/b]
唤醒等待这个对象的监视器的单一线程。如果有很多线程在等待该对象监视器,则选择其中的一个来唤醒。这歌选择是任意的,与具体的实现相关。一个线程调用wait方法后就等待对象监视器。被唤醒的线程将在当前线程放弃对象锁后才能继续执行,它在竞争该对象锁方面没有任何可靠的特权或劣势。调用这个方法必须占有对象监视器。线程通过3中途径可以占有对象监视器:
(1)执行对象的同步方法;
(2)执行锁定对象的同步语句块;
(3)执行类对象的静态同步方法。
在某一时刻,只有一个线程占有对象监视器。该方法必须同步执行的,否则会抛出illegalmonitorstateexception。
通过下面的一个例子来说明:
输出:
[b][color=green]t1获取synobj的对象监视器,开始执行同步块
t2启动,但是因为t1占用了synobj的对象监视器,则等待t1执行synobj.wait来释放它
t1在 wait()时挂起了
在t1执行synobj.wait后,t2获取synobj的对象监视器,进入同步块
t2执行synobj.notify(),t1被唤醒,但t2还在同步块中,没有释放synobj的对象监视器,t1等待synobj的对象监视器
t2结束同步块,释放synobj的对象监视器,t1获取到synobj的对象监视器,并执行wait后面的操作
t1被t2唤醒后并重新获得synobj的对象监视器,继续执行
t1获取synobj的对象监视器,结束同步块 [/color][/b]
注意,对象监视器就是对象锁,在object.notify()后,被唤醒的线程还不能立即执行,必须等待到对象锁。
导致当前线程等待,直到该对象的notify或notifyall被执行。换句话说,这个方法行为效果完全与简单调用wait(0)一样。当前线程必须拥有对象监视器。线程释放对象监视器的所有权,等待直到另一个线程通过调用notify或notifyall来通知等待对象监视器的线程们并唤醒。然后,当前线程等待重新获取对象监视器并继续执行。因为在一个参数的版本中,中断与伪唤醒是可能的,这个方法应该通常在一个循环中使用:
synchronized (obj) {
while (<condition does not hold>)
obj.wait();
... // perform action appropriate to condition
}
该方法必须同步执行的,否则会抛出illegalmonitorstateexception。
[b]认识object.wait(long)方法:[/b]
基本功能与object.wait()相同,只是在指定时间间隔后,当前线程自动唤醒,并与其它线程竞争对象监视器,在获取对象监视器后,当前线程继续向前执行。
[b]认识object.notify方法:[/b]
唤醒等待这个对象的监视器的单一线程。如果有很多线程在等待该对象监视器,则选择其中的一个来唤醒。这歌选择是任意的,与具体的实现相关。一个线程调用wait方法后就等待对象监视器。被唤醒的线程将在当前线程放弃对象锁后才能继续执行,它在竞争该对象锁方面没有任何可靠的特权或劣势。调用这个方法必须占有对象监视器。线程通过3中途径可以占有对象监视器:
(1)执行对象的同步方法;
(2)执行锁定对象的同步语句块;
(3)执行类对象的静态同步方法。
在某一时刻,只有一个线程占有对象监视器。该方法必须同步执行的,否则会抛出illegalmonitorstateexception。
通过下面的一个例子来说明:
final object synobj = new object(); thread t1 = new thread(new runnable() { @override public void run() { synchronized(synobj) { system.out.println("t1获取synobj的对象监视器,开始执行同步块"); try { timeunit.minutes.sleep(1); system.out.println("t1在 wait()时挂起了"); synobj.wait(); system.out.println("t1被t2唤醒后并重新获得synobj的对象监视器,继续执行"); }catch(interruptedexception e) { e.printstacktrace(); } system.out.println("t1获取synobj的对象监视器,结束同步块"); } };});t1.start();thread t2 = new thread(new runnable() { @override public void run() { system.out.println("t2启动,但是因为t1占用了synobj的对象监视器,则等待t1执行synobj.wait来释放它"); synchronized(synobj) { try { system.out.println("在t1执行synobj.wait后,t2获取synobj的对象监视器,进入同步块"); synobj.notify(); system.out.println("t2执行synobj.notify(),t1被唤醒,但t2还在同步块中,没有释放synobj的对象监视器,t1等待synobj的对象监视器"); timeunit.minutes.sleep(1); system.out.println("t2结束同步块,释放synobj的对象监视器,t1获取到synobj的对象监视器,并执行wait后面的操作"); }catch(interruptedexception e) { e.printstacktrace(); } } };});t2.start();
输出:
[b][color=green]t1获取synobj的对象监视器,开始执行同步块
t2启动,但是因为t1占用了synobj的对象监视器,则等待t1执行synobj.wait来释放它
t1在 wait()时挂起了
在t1执行synobj.wait后,t2获取synobj的对象监视器,进入同步块
t2执行synobj.notify(),t1被唤醒,但t2还在同步块中,没有释放synobj的对象监视器,t1等待synobj的对象监视器
t2结束同步块,释放synobj的对象监视器,t1获取到synobj的对象监视器,并执行wait后面的操作
t1被t2唤醒后并重新获得synobj的对象监视器,继续执行
t1获取synobj的对象监视器,结束同步块 [/color][/b]
注意,对象监视器就是对象锁,在object.notify()后,被唤醒的线程还不能立即执行,必须等待到对象锁。