Java并发编程深入学习——生产者-消费者模式多种实现方式
来源:互联网 发布:易语言取中间文本源码 编辑:程序博客网 时间:2024/05/17 08:22
问题介绍
生产者消费者模型是经典的同步问题。问题大致如下:当队列满时,生产者需要等待队列有空间才能继续往里面放入商品,而在等待的期间内,生产者必须释放对临界资源(即队列)的占用权。因为生产者如果不释放对临界资源的占用权,那么消费者就无法消费队列中的商品,就不会让队列有空间,那么生产者就会一直无限等待下去。因此,一般情况下,当队列满时,会让生产者交出对临界资源的占用权,并进入挂起状态。然后等待消费者消费了商品,然后消费者通知生产者队列有空间了。同样地,当队列空时,消费者也必须等待,等待生产者通知它队列中有商品了。这种互相通信的过程就是线程间的协作。
下面总结了三种方式来实现一个消费者/生产者模型.
1.wait/notify模式
/** * wait and notify * 生产者和消费者问题 * * @author bridge */public class test1 { public static void main(String[] args) { Resource resource = new Resource(); //生产者线程 ProducerThread p = new ProducerThread(resource); //多个消费者 ConsumerThread c1 = new ConsumerThread(resource); ConsumerThread c2 = new ConsumerThread(resource); ConsumerThread c3 = new ConsumerThread(resource); p.start(); c1.start(); c2.start(); c3.start(); }}class ProducerThread extends Thread { private Resource resource; public ProducerThread(Resource resource) { this.resource = resource; //setName("生产者"); } public void run() { while (true) { try { Thread.sleep((long) (1000 * Math.random())); } catch (InterruptedException e) { e.printStackTrace(); } resource.add(); } }}class ConsumerThread extends Thread { private Resource resource; public ConsumerThread(Resource resource) { this.resource = resource; //setName("消费者"); } public void run() { while (true) { try { Thread.sleep((long) (1000 * Math.random())); } catch (InterruptedException e) { e.printStackTrace(); } resource.remove(); } }}/** * 公共资源类 */class Resource { //当前资源数量 private int num = 0; //资源池中允许存放的资源数 private int size = 10; /*** * 向资源池中添加资源 */ public synchronized void add() { if (num < size) { num++; System.out.println(Thread.currentThread().getName() + "生产一件资源,当前资源池有" + num + "个"); notifyAll(); } else { try { wait(); System.out.println(Thread.currentThread().getName() + "线程进入等待"); } catch (InterruptedException e) { e.printStackTrace(); } } } /** * 从资源池中取走资源 */ public synchronized void remove() { if (num > 0) { num--; System.out.println("消费者" + Thread.currentThread().getName() + "消耗一件资源," + "当前资源池有" + num + "个"); notifyAll(); } else { try { wait(); System.out.println(Thread.currentThread().getName() + "线程进入等待"); } catch (InterruptedException e) { e.printStackTrace(); } } }}
2.Lock condition模式
package ProducerAndConsumer.p2;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;/** * lock和condition解法 * 生产者和消费者问题 * * @author bridge */public class test2 { public static void main(String[] args) { Lock lock = new ReentrantLock(); Condition pCondition = lock.newCondition(); Condition cCondition = lock.newCondition(); Resource resource = new Resource(lock, pCondition, cCondition); //生产者线程 ProducerThread p = new ProducerThread(resource); //多个消费者 ConsumerThread c1 = new ConsumerThread(resource); ConsumerThread c2 = new ConsumerThread(resource); ConsumerThread c3 = new ConsumerThread(resource); p.start(); c1.start();// c2.start();// c3.start(); }}/** * 生产者线程 */class ProducerThread extends Thread { private Resource resource; public ProducerThread(Resource resource) { this.resource = resource; setName("生产者"); } public void run() { while (true) { try { Thread.sleep((long) (1000 * Math.random())); } catch (InterruptedException e) { e.printStackTrace(); } resource.add(); } }}/** * 消费者线程 */class ConsumerThread extends Thread { private Resource resource; public ConsumerThread(Resource resource) { this.resource = resource; //setName("消费者"); } public void run() { while (true) { try { Thread.sleep((long) (1000 * Math.random())); } catch (InterruptedException e) { e.printStackTrace(); } resource.remove(); } }}/** * 公共资源类 */class Resource { //当前资源数量 private int num = 0; //资源池中允许存放的资源数 private int size = 10; private Lock lock; private Condition pCondition; private Condition cCondition; public Resource(Lock lock, Condition pCondition, Condition cCondition) { this.lock = lock; this.pCondition = pCondition; this.cCondition = cCondition; } /*** * 向资源池中添加资源 */ public void add() { lock.lock(); try { if (num < size) { num++; System.out.println(Thread.currentThread().getName() + "生产一件资源,当前资源池有" + num + "个"); //唤醒等待的消费者 cCondition.signalAll(); } else { //使生产者等待 pCondition.await(); System.out.println(Thread.currentThread().getName() + "线程进入等待"); } } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } /** * 从资源池中取走资源 */ public void remove() { lock.lock(); try { if (num > 0) { num--; System.out.println("消费者" + Thread.currentThread().getName() + "消耗一件资源," + "当前资源池有" + num + "个"); pCondition.signalAll(); //唤醒等待的生产者 } else { try { cCondition.await(); //使消费者等待 System.out.println(Thread.currentThread().getName() + "线程进入等待"); } catch (InterruptedException e) { e.printStackTrace(); } } } finally { lock.unlock(); } }}
3.阻塞队列模式
package ProducerAndConsumer.p3;import java.util.concurrent.BlockingQueue;import java.util.concurrent.LinkedBlockingQueue;/** * 阻塞队列解法 * 生产者和消费者问题 * * @author bridge */public class test3 { public static void main(String[] args) { Resource resource = new Resource(); //生产者线程 ProducerThread p = new ProducerThread(resource); //多个消费者 ConsumerThread c1 = new ConsumerThread(resource); ConsumerThread c2 = new ConsumerThread(resource); ConsumerThread c3 = new ConsumerThread(resource); p.start(); c1.start(); // c2.start(); // c3.start(); }}class ProducerThread extends Thread { private Resource resource; public ProducerThread(Resource resource) { this.resource = resource; //setName("生产者"); } public void run() { while (true) { try { Thread.sleep((long) (1000 * Math.random())); } catch (InterruptedException e) { e.printStackTrace(); } resource.add(); } }}class ConsumerThread extends Thread { private Resource resource; public ConsumerThread(Resource resource) { this.resource = resource; //setName("消费者"); } public void run() { while (true) { try { Thread.sleep((long) (1000 * Math.random())); } catch (InterruptedException e) { e.printStackTrace(); } resource.remove(); } }}/** * 公共资源类 */class Resource { private BlockingQueue resourceQueue = new LinkedBlockingQueue(10); /*** * 向资源池中添加资源 */ public void add() { try { resourceQueue.put(1); System.out.println("生产者" + Thread.currentThread().getName() + "生产一件资源," + "当前资源池有" + resourceQueue.size() + "个资源"); } catch (InterruptedException e) { e.printStackTrace(); } } /** * 从资源池中取走资源 */ public void remove() { try { resourceQueue.take(); System.out.println("消费者" + Thread.currentThread().getName() + "消耗一件资源," + "当前资源池有" + resourceQueue.size() + "个资源"); } catch (InterruptedException e) { e.printStackTrace(); } }}
0 0
- Java并发编程深入学习——生产者-消费者模式多种实现方式
- 生产者消费者的多种java实现方式
- Java并发编程:阻塞队列及实现生产者-消费者模式
- Java并发编程 生产者消费者模式
- Java并发编程:生产者-消费者模式
- Java并发编程:生产者消费者模式
- Java并发学习--生产者/消费者模式
- 生产者/消费者模式Java实现方式
- 生产者/消费者问题的多种Java实现方式
- 生产者/消费者问题的多种Java实现方式
- 生产者/消费者问题的多种Java实现方式
- 生产者/消费者问题的多种Java实现方式
- 生产者/消费者问题的多种Java实现方式
- 生产者/消费者问题的多种Java实现方式
- 生产者/消费者问题的多种Java实现方式
- 生产者/消费者问题的多种Java实现方式
- 生产者/消费者问题的多种Java实现方式
- 生产者/消费者问题的多种Java实现方式
- PHP反射机制
- 比较好用的.NET后台GET方式代码
- FFMPEG中关于rtmp的研究
- 学习Mybatis(一)
- DataGridView行设置背景颜色+Var类型+筛选
- Java并发编程深入学习——生产者-消费者模式多种实现方式
- Java虚拟机(九)——多态性理解
- ThinkPHP 读取配置信息与动态配置(C方法)
- iOS设置行高的多种方式以及优先级区分
- C++笔试总结
- php中多种方法删除字符串中间的空格
- 软件调试学习(1)——分段地址,线性地址,物理地址
- 一个输出内容不同引发的问题
- LIS学习总结