Guarded Suspension
当线程需要一些资源准备的时候才可以运行的时候就最好使用Guarded Suspension,对使用资源的部分使用保卫空间,不满足就wait(),对补充资源的地方使用notifyAll/notify 两种通知等待线程。这个时候其实也发现了,使用资源的线程和补充资源的线程不应该是同一个,不然就会永远等待了。
public class Main { public static void main(String args[]){ RequestQueue requestQueue=new RequestQueue(); new ClientThread(requestQueue, "chen", 10000).start(); new ServerThread(requestQueue, "cdk", 3000).start(); } } //使用添加资源的线程的地方 public class ClientThread extends Thread { private Random random; private RequestQueue requestQueue; public ClientThread(RequestQueue requestQueue,String name,long seed) { super(name); this.requestQueue=requestQueue; this.random=new Random(seed); } public void run(){ for(int i=0;i<1000;i++){ Request request=new Request("no."+i); System.out.println(Thread.currentThread().getName()+" request "+request); requestQueue.putRequest(request); try{ Thread.sleep(1000); }catch(InterruptedException e){ } } } } //使用资源线程 public class ServerThread extends Thread{ private Random random; private RequestQueue requestQueue; public ServerThread(RequestQueue requestQueue,String name,long seed) { super(name); this.requestQueue=requestQueue; random=new Random(seed); } public void run(){ for(int i=0;i<1000;i++){ Request request=requestQueue.getRequest(); System.out.println(Thread.currentThread().getName()+" handler "+request); try{ Thread.sleep(3000); }catch(InterruptedException e){ } } } } public class Request { private final String name; public Request(String name) { this.name=name; } public String getName(){ return name; } public String toString(){ return "[request "+ name+" ]"; } } //资源缓存区,同时也是定义线程行为的地方 public class RequestQueue { private final LinkedList queue = new LinkedList(); public synchronized Request getRequest() { while (queue.size() <= 0) { try { wait(); } catch (InterruptedException e) { } } return (Request) queue.removeFirst(); } public synchronized void putRequest(Request request){ queue.add(request); notifyAll(); }}
这种模式的情况就是,线程获取数据需要一些条件的情况下,而且既要有等待线程,也要有唤醒线程。