训练营学习笔记 java多线程(五)生产者/消费者
2012-04-26 22:02
465 查看
下面是一个经典的生产者消费者的例子。假设使用缓冲区存储整数,缓冲区的大小是受限制的。缓冲区提供write(int)方法将一个整数添加到缓冲区,还体统read()方法从缓冲区中读取并删除一个整数。为了同步操作,使用具有两个条件的锁,notEmpty(缓冲区非空)和notFull(缓冲区未满)。当任务相缓冲区添加爱一个int时,如果缓冲区是满的,那么任务将等待notFull状态,当任务从缓冲区总删除一个int时,如果缓冲区是空的,那么任务将等待notEmpty状态。
![](http://my.csdn.net/uploads/201204/26/1335448843_4120.png)
阻塞列队
阻塞列队在试图想一个满列队添加元素或这从空列队删除元素时会导致线程阻塞。BlockQueue接口扩展java.util.queue,并且提供同步的put和take方法想列队头部添加元素,以及从列队尾删除元素。
java支持三个具体的阻塞列队ArrayBlockingQueue、LinkedblockingQueue 和 PriorityBlockingQueue ,他们都在java。util.concurrent抱中。ArrayBlockingQueue使用数组实现阻塞列队,必须指定一个容量可选的公平性锁来构造ArrayBlocking。LinkedBlockingQueue使用链表来实现阻塞列队。可以创建不受限制或受限制的LinkedBlockingQueue。PriorityBlockingQueue
是优先列队,可以创建不受限或这受限的优先列队。对于不受限的LinkedBlockingQueue和PriorityBlockingQueue而言,put方法将永远不会阻塞线程。
![](http://my.csdn.net/uploads/201204/27/1335504117_2107.jpg)
可以使用阻塞列队替换生产者,消费者中的Buffer 来精简生产者和消费者模式。
作者:duanmengchao 发表于2012-4-26 22:01:42 原文链接
阅读:14 评论:0 查看评论
![](http://my.csdn.net/uploads/201204/26/1335448843_4120.png)
package LianXi; import java.util.*; import java.util.concurrent.*; import java.util.concurrent.locks.*; public class ConsumerProducer{ private static Buffer _buffer = new Buffer(); public static void main(String[] args) { ExecutorService executor = Executors.newCachedThreadPool(); executor.execute(new ConsumerTask()); executor.execute(new ProducerTask()); } public static class ConsumerTask implements Runnable{ @Override public void run(){ while(true) _buffer.read(); } } public static class ProducerTask implements Runnable{ @Override public void run(){ while(true) _buffer.write((int)(Math.random()*1000000)); } } public static class Buffer{ private static final int CAPACITY=10; private LinkedList<Integer> _queue = new LinkedList<Integer>(); private static Lock _lock = new ReentrantLock(); private static Condition notEmpty = _lock.newCondition(); //不为空条件 private static Condition notFull = _lock.newCondition(); //未满条件 //返回Buffer的整数个数 public int getSize(){ return _queue.size(); } //是否为空 public boolean isEmpty(){ return _queue.isEmpty(); } //是否满了 public boolean isFull(){ return getSize()>=CAPACITY; } //添加一个整数到缓冲区 public void write(int integer){ _lock.lock(); try{ while(isFull()){ System.out.println("\n缓冲区已满,等待读取任务\n"); notFull.await(); } _queue.push(integer); System.out.println("\n想缓冲区中添加了"+integer); notEmpty.signalAll(); Thread.sleep(500); } catch(InterruptedException ex) { ex.printStackTrace(); } finally { _lock.unlock(); } } //读取并删除 public int read(){ int result = 0; _lock.lock(); try{ while( isEmpty( ) ){ System.out.println("\n缓冲区以为空,等待写入任务\n"); notEmpty.await(); } result = _queue.remove(); notFull.signalAll(); Thread.sleep(500); System.out.println("\n从缓冲区中读取了"+result); } catch(InterruptedException ex) { ex.printStackTrace(); } finally { _lock.unlock(); return result; } } } }
阻塞列队
阻塞列队在试图想一个满列队添加元素或这从空列队删除元素时会导致线程阻塞。BlockQueue接口扩展java.util.queue,并且提供同步的put和take方法想列队头部添加元素,以及从列队尾删除元素。
java支持三个具体的阻塞列队ArrayBlockingQueue、LinkedblockingQueue 和 PriorityBlockingQueue ,他们都在java。util.concurrent抱中。ArrayBlockingQueue使用数组实现阻塞列队,必须指定一个容量可选的公平性锁来构造ArrayBlocking。LinkedBlockingQueue使用链表来实现阻塞列队。可以创建不受限制或受限制的LinkedBlockingQueue。PriorityBlockingQueue
是优先列队,可以创建不受限或这受限的优先列队。对于不受限的LinkedBlockingQueue和PriorityBlockingQueue而言,put方法将永远不会阻塞线程。
![](http://my.csdn.net/uploads/201204/27/1335504117_2107.jpg)
可以使用阻塞列队替换生产者,消费者中的Buffer 来精简生产者和消费者模式。
作者:duanmengchao 发表于2012-4-26 22:01:42 原文链接
阅读:14 评论:0 查看评论
相关文章推荐
- java学习笔记之多线程生产者与消费者
- Java基础学习6_多线程(线程间通信--生产者消费者)
- JAVA学习第二十七课(多线程(六))- 多生产者多消费者问题(JDK1.5新特性)
- java学习多线程之生产者消费者
- JAVA学习笔记(四十二)-生产者消费者模型
- Java 多线程学习之生产者消费者模型:一个较完善的实现
- Java多线程学习之生产者消费者问题(一)
- JAVA笔记14__多线程共享数据(同步)/ 线程死锁 / 生产者与消费者应用案例 / 线程池
- java多线程学习生产者消费者
- JAVA多线程学习--生产者消费者问题
- java多线程学习之生产者与消费者(二)
- <JAVA学习笔记8>——生产者、消费者案例(2)
- Java多线程学习笔记--生产消费者模式
- JAVA学习笔记(1)_____模拟线程通信之生产者消费者问题
- Java基础学习__多线程(线程间通信--生产者消费者JDK5.0升级版)
- Java多线程学习笔记--生产消费者模式
- [好程序员训练营]----java基础之多线程部分学习笔记
- <JAVA学习笔记7>——生产者、消费者案例(1)
- JAVA学习第二十七课(多线程(六))- 多生产者多消费者问题(JDK1.5新特性)
- Java多线程学习之 BlockingQueue实现生产者和消费者模型