多线程之生产者-消费者
来源:互联网 发布:芒果店长软件下载 编辑:程序博客网 时间:2024/05/22 12:56
生产者-消费者模型就是生产者每生产一个资源,消费者消费一个资源,不管生产者或者消费者有多少个。这里模拟用多线程技术实现生产者-消费者模型。
本文以两种方式实现生产者-消费者模型。
1、传统的同步方式,实现多个线程的生产者-消费者模型
这里使用了synchronized对操作共享资源的方法同步,即同一时刻只有一个线程操作共享资源,其他线程处于等待状态,直到当前线程操作完成,然后等待被唤醒。
Producer代码:
package com.deppon.foss.multithred;/** * * <p>生产者</p> * @author Stephen * @version 1.0 * @date 2015-4-6 */public class Producer implements Runnable {private Resource resource;public Producer(Resource resource) {this.resource = resource;}@Overridepublic void run() {while(true){resource.put("+商品+");}}}
Consumer代码:
package com.deppon.foss.multithred;/** * * <p>消费者</p> * @author Stephen * @version 1.0 * @date 2015-4-6 */public class Consumer implements Runnable {private Resource resource;public Consumer(Resource resource) {this.resource = resource;}@Overridepublic void run() {while(true){resource.take();}}}
Resource代码:
代码里面有两个方法:put()生产资源,take()取资源,方法都是同步的。代码里开启了四个线程,两个线程负责生产资源,两个线程负责消费资源。
需要注意的地方:
- 这里不能if判断,只能用while循环来判断。
- 这里只能用notifyAll()方法,把所有在等待的线程唤醒,如果用notify()方法,不能保证消费的线程被唤醒。
package com.deppon.foss.multithred;/** * * <p>生产者-消费者案例研究</p> * if只判断一次,while重复判断<br/> * notify()唤醒先在池中等待的线程,notifyAll()唤醒所有在等待的线程 * @author Stephen * @version 1.0 * @date 2015-4-6 */public class Resource {private String name;private boolean flag = false; //标记private int count = 0;/** * * <p>生产方法</p> * @author Stephen * @version 1.0 */public synchronized void put(String name){while (flag) {try {this.wait();} catch (InterruptedException e) {flag = true;}}this.name = name + "--" +(++count);System.out.println(Thread.currentThread().getName() + "..生产者.." + this.name);flag = true;this.notifyAll(); }/** * * <p>消费方法</p> * @author Stephen * @version 1.0 */public synchronized void take(){while (!flag) {try {this.wait();} catch (InterruptedException e) {flag = false;}}System.out.println(Thread.currentThread().getName() + ".......消费者......." + this.name);flag = false;this.notifyAll();}public static void main(String[] args) {Resource resource = new Resource();Producer producer = new Producer(resource);Consumer consumer = new Consumer(resource);new Thread(producer).start();new Thread(producer).start();new Thread(consumer).start();new Thread(consumer).start();}}
运行上述代码,可以看出每生产一个资源就被消费者取走。
2、使用Lock和Condition实现生产者-消费者模型。
Producer代码:
package com.deppon.foss.multithred;/** * * <p>生产者</p> * @author Stephen * @version 1.0 * @date 2015-4-6 */public class ConditionProducer implements Runnable {private ConditionResource resource;public ConditionProducer(ConditionResource resource) {this.resource = resource;}@Overridepublic void run() {while(true){resource.put("+商品+");}}}
Consumer代码:
package com.deppon.foss.multithred;/** * * <p>消费者</p> * @author Stephen, 刘欣雨, 219321 * @version 1.0 * @date 2015-4-6 */public class ConditionConsumer implements Runnable {private ConditionResource resource;public ConditionConsumer(ConditionResource resource) {this.resource = resource;}@Overridepublic void run() {while(true){resource.take();}}}
Resource代码:
代码里面有两个方法:put()生产资源,take()取资源。代码里开启了四个线程,两个线程负责生产资源,两个线程负责消费资源。
需要注意的地方:
- 这里不能if判断,只能用while循环来判断。
- 这里使用了两个Condition,一个是生产资源的条件,一个是消费资源的条件,这样做效率更高,每次唤醒不用唤醒左右的线程,只需唤醒对象的线程即可。
package com.deppon.foss.multithred;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;/** * * <p>生产者-消费者案例研究,使用Lock和Condition</p> * 使用两个Condition,实现细粒度的控制 * @author Stephen * @version 1.0 * @date 2015-4-6 */public class ConditionResource {private String name;private boolean flag = false; //标记private int count = 0;private Lock lock = new ReentrantLock();private Condition proCondition = lock.newCondition();private Condition conCondition = lock.newCondition();/** * * <p>生产方法</p> * @author Stephen * @version 1.0 */public void put(String name){lock.lock();try {while (flag) {proCondition.await();}this.name = name + "--" +(++count);System.out.println(Thread.currentThread().getName() + "..生产者.." + this.name);flag = true;conCondition.signal();} catch (InterruptedException e) {flag = true;} finally {lock.unlock();}}/** * * <p>消费方法</p> * @author Stephen * @version 1.0 */public void take(){lock.lock();try {while (!flag) {conCondition.await();}System.out.println(Thread.currentThread().getName() + ".......消费者......." + this.name);flag = false;proCondition.signal();} catch (InterruptedException e) {flag = false;} finally {lock.unlock();}}public static void main(String[] args) {ConditionResource resource = new ConditionResource();ConditionProducer producer = new ConditionProducer(resource);ConditionConsumer consumer = new ConditionConsumer(resource);new Thread(producer).start();new Thread(producer).start();new Thread(consumer).start();new Thread(consumer).start();}}
运行上述代码,可以看出每生产一个资源就被消费者取走。
对上述两种方式进行比较分析后,可以知道,使用Lock和Condition的方式要明显优于使用synchronized,前者减少没次唤醒线程的数量,做到更细粒度的控制,在并发量大的情况下,明显有优势。
0 0
- 多线程之生产者-消费者
- 多线程之生产者消费者
- 多线程之生产者-消费者
- 多线程之生产者消费者
- 多线程之生产者消费者
- 多线程之:生产者消费者
- 多线程之生产者消费者模型
- [Java]多线程之生产者消费者
- 多线程之生产者消费者模型
- 多线程之生产者消费者问题
- 多线程之生产者消费者问题
- 多线程之生产者消费者问题
- 多线程之生产者消费者模型
- 多线程编程之生产者消费者
- 多线程之生产者消费者问题
- 多线程之生产者消费者模式
- 多线程之生产者-消费者模式
- 多线程之生产者消费者模型
- iOS开发-缓存图片到沙盒
- Linux 标准目录结构
- UGUI Make Use Of Grid Layout Group
- 第五周 程序阅读——static(1)
- 派生类的指针绑定到基类的对象(编译通过,但结果不可预知)
- 多线程之生产者-消费者
- oracle登录无响应问题解决方法(oracle4612267补丁安装教程)
- 常用类"三"(BigInteger,BigDecimal,Date)
- 数据集的基本信息(二)
- Visual Studio工程里的自定义宏
- 蓝桥杯-基础练习-数列排序
- viewstatus
- 继承
- 计算机网络之 网络层