# obj.notifyAll()则能全部唤醒 A1,A2,A3,但是要继续执行 obj.wait()的下一条语句,必须获
得 obj 锁,因此,A1,A2,A3 只有一个有机会获得锁继续执行,例如 A1,其余的需要等待
A1 释放 obj 锁之后才能继续执行。
# 当 B 调用 obj.notify/notifyAll 的时候,B 正持有 obj 锁,因此,A1,A2,A3 虽被唤醒,但是
仍无法获得 obj 锁。直到 B 退出 synchronized 块,释放 obj 锁后,A1,A2,A3 中的一个才有机
会获得锁继续执行。
前面讲了 wait/notify 机制,Thread 还有一个 sleep()静态方法,它也能使线程暂停一段时间。
sleep 与 wait 的不同点是: sleep 并不释放锁,并且 sleep 的暂停和 wait 暂停是不一样的。
obj.wait 会使线程进入 obj 对象的等待集合中并等待唤醒。
但是 wait()和 sleep()都可以通过 interrupt()方法打断线程的暂停状态,从而使线程立刻抛出
InterruptedException。
如果线程 A 希望立即结束线程 B,则可以对线程 B 对应的 Thread 实例调用 interrupt 方法。
如果此刻线程 B 正在 wait/sleep/join,则线程 B 会立刻抛出 InterruptedException,在
catch() {} 中直接 return 即可安全地结束线程。
需要注意的是,InterruptedException 是线程自己从内部抛出的,并不是 interrupt()方法抛出
的。对某一线程调用 interrupt()时,如果该线程正在执行普通的代码,那么该线程根本就不
会抛出 InterruptedException。但是,一旦该线程进入到 wait()/sleep()/join()后,就会立刻抛出
InterruptedException。
GuardedSuspention 模式主要思想是:
当条件不满足时,线程等待,直到条件满足时,等待该条件的线程被唤醒。
我们设计一个客户端线程和一个服务器线程,客户端线程不断发送请求给服务器线程,服务
器线程不断处理请求。当请求队列为空时,服务器线程就必须等待,直到客户端发送了请求。
先定义一个请求队列:Queue
package com.crackj2ee.thread;
import java.util.*;
public class Queue {
private List queue = new LinkedList();