浏览 2512 次
锁定老帖子 主题:多线程设计模式 -- suspension
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (4)
|
|
---|---|
作者 | 正文 |
发表时间:2009-07-09
最后修改:2009-07-09
请求对象 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 { //采用LinkedList 保存客户请求 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.addLast(request); notifyAll();//唤醒wait()方法,执行程序 } } 工作缓存器jdk1.5新特性实现 public class RequestQueue { private final LinkedList queue = new LinkedList(); private Lock lock = new ReentrantLock(); private Condition serverCondition = lock.newCondition(); private Condition clientCondition = lock.newCondition(); public Request getRequest() { lock.lock(); try { while (queue.size() <= 0) { //类似wait(); serverCondition.await(); } } catch (InterruptedException e) { } finally { lock.unlock(); } return (Request) queue.removeFirst(); } public void putRequest(Request request) { lock.lock(); try { queue.addLast(request); //类似notifyAll(); clientCondition .signalAll(); } finally { lock.unlock(); } } } 工作缓存器jdk1.5新特性实现 public class NewRequestQueue { //一个特殊的Queue下面有详细的说明 private final static BlockingQueue<Request> basket = new ArrayBlockingQueue<Request>( 10);; public Request getRequest() { try { return basket.take(); } catch (Exception e) { throw new RuntimeException(e); } } public void putRequest(Request request) { try { basket.put(request); } catch (Exception e) { throw new RuntimeException(e); } } } BlockingQueue 是一种特殊的Queue,若BlockingQueue 是空的,从 BlockingQueue 取东西的操作将会被阻断进入等待状态直到BlocingkQueue 进 了新货才会被唤醒。同样,如果BlockingQueue 是满的任何试图往里存东西的 操作也会被阻断进入等待状态,直到BlockingQueue 里有新的空间才会被唤醒 继续操作。BlockingQueue 提供的方法主要有: add(anObject): 把anObject 加到BlockingQueue 里,如果 BlockingQueue 可以容纳返回true,否则抛出IllegalStateException 异常。 offer(anObject):把anObject 加到BlockingQueue 里,如果 BlockingQueue 可以容纳返回true,否则返回false。 put(anObject):把anObject 加到BlockingQueue 里,如果BlockingQueue 没有空间,调用此方法的线程被阻断直到BlockingQueue 里有新的空间再继 续。 poll(time):取出BlockingQueue 里排在首位的对象,若不能立即取出可 等time 参数规定的时间。取不到时返回null。 take():取出BlockingQueue 里排在首位的对象,若BlockingQueue 为 空,阻断进入等待状态直到BlockingQueue 有新的对象被加入为止。 根据不同的需要 BlockingQueue 有4 种具体实现: ArrayBlockingQueue:规定大小的BlockingQueue,其构造函数必须带 一个int 参数来指明其大小。其所含的对象是以FIFO(先入先出)顺序排序 的。 LinkedBlockingQueue:大小不定的BlockingQueue,若其构造函数带一 个规定大小的参数,生成的BlockingQueue 有大小限制,若不带大小参数, 所生成的BlockingQueue 的大小由Integer.MAX_VALUE 来决定。其所含的 对象是以FIFO(先入先出)顺序排序的。LinkedBlockingQueue 和 ArrayBlockingQueue 比较起来,它们背后所用的数据结构不一样,导致 LinkedBlockingQueue 的数据吞吐量要大于ArrayBlockingQueue,但在线程 数量很大时其性能的可预见性低于ArrayBlockingQueue。 PriorityBlockingQueue:类似于LinkedBlockingQueue,但其所含对象的 排序不是FIFO,而是依据对象的自然排序顺序或者是构造函数所带的 Comparator 决定的顺序。 SynchronousQueue:特殊的BlockingQueue,对其的操作必须是放和取 交替完成的。 客户线程 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 < 10000; i++) { Request request = new Request("No." + i); System.out.println(Thread.currentThread().getName() + " requests " + request); //放入请求 requestQueue.putRequest(request); try { Thread.sleep(random.nextInt(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; this.random = new Random(seed); } public void run() { for (int i = 0; i < 10000; i++) { Request request = requestQueue.getRequest(); System.out.println(Thread.currentThread().getName() + " handles " + request); try { Thread.sleep(random.nextInt(1000)); } catch (InterruptedException e) { } } } } 测试类 public class Main { public static void main(String[] args) { RequestQueue requestQueue = new RequestQueue(); new ClientThread(requestQueue, "Alice", 3141592L).start(); new ServerThread(requestQueue, "Bobby", 6535897L).start(); } } 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-07-09
LZ,文字部分好像没有一句是你自己整理的吧。
引用 BlockingQueue 是一种特殊的Queue,若BlockingQueue 是空的,从 BlockingQueue 取东西的操作将会被阻断进入等待状态直到BlocingkQueue 进 了新货才会被唤醒。同样,如果BlockingQueue 是满的任何试图往里存东西的 操作也会被阻断进入等待状态,直到BlockingQueue 里有新的空间才会被唤醒 继续操作。BlockingQueue 提供的方法主要有: add(anObject): 把anObject 加到BlockingQueue 里,如果 BlockingQueue 可以容纳返回true,否则抛出IllegalStateException 异常。 offer(anObject):把anObject 加到BlockingQueue 里,如果 BlockingQueue 可以容纳返回true,否则返回false。 put(anObject):把anObject 加到BlockingQueue 里,如果BlockingQueue 没有空间,调用此方法的线程被阻断直到BlockingQueue 里有新的空间再继 续。 poll(time):取出BlockingQueue 里排在首位的对象,若不能立即取出可 等time 参数规定的时间。取不到时返回null。 take():取出BlockingQueue 里排在首位的对象,若BlockingQueue 为 空,阻断进入等待状态直到BlockingQueue 有新的对象被加入为止。 根据不同的需要 BlockingQueue 有4 种具体实现: ArrayBlockingQueue:规定大小的BlockingQueue,其构造函数必须带 一个int 参数来指明其大小。其所含的对象是以FIFO(先入先出)顺序排序 的。 LinkedBlockingQueue:大小不定的BlockingQueue,若其构造函数带一 个规定大小的参数,生成的BlockingQueue 有大小限制,若不带大小参数, 所生成的BlockingQueue 的大小由Integer.MAX_VALUE 来决定。其所含的 对象是以FIFO(先入先出)顺序排序的。LinkedBlockingQueue 和 ArrayBlockingQueue 比较起来,它们背后所用的数据结构不一样,导致 LinkedBlockingQueue 的数据吞吐量要大于ArrayBlockingQueue,但在线程 数量很大时其性能的可预见性低于ArrayBlockingQueue。 PriorityBlockingQueue:类似于LinkedBlockingQueue,但其所含对象的 排序不是FIFO,而是依据对象的自然排序顺序或者是构造函数所带的 Comparator 决定的顺序。 SynchronousQueue:特殊的BlockingQueue,对其的操作必须是放和取 交替完成的。 |
|
返回顶楼 | |