生产者消费者模型(多个生产者和多个消费者)JDK1.5 (Lock&Condition)实现版
来源:互联网 发布:mac能装steam吗 编辑:程序博客网 时间:2024/05/16 13:46
生产者消费者模型(多个生产者和多个消费者)JDK1.5 (Lock&Condition)实现版
场景描述
多线程开发中很经典的一个案例就是生产者消费者模型,它们共享资源,但是对资源的操作方式并不同。因此它们需要协调资源,否则就会出现线程安全问题。尤其当时多个生产者和多个消费者时比较麻烦。本文以JDK1.5并发工具包下的Lock和Condition来实现多生产者多消费者模型。
代码展示
Resource Code
/*** 生产者和消费者共享的资源Resource对象* @author xuyi3* @2016年4月7日 @下午2:01:21* @Resource* @功能说明:<br>* @春风十里不如你* @备注:使用Lock 和 Condition实现多生产者和多消费者模型*/public class Resource { /** 资源名称 */ private String name; /** 资源标识符 */ private boolean flag = false; // 区分产品的计数器 private int count = 0; // 定义一个锁 Lock lock = new ReentrantLock(); // 生产者的监视器 Condition conditionProduce = lock.newCondition(); // 消费者的监视器 Condition conditionConsumer = lock.newCondition(); /** * 生产产品方法 * @param threadName */ public void produce(String threadName) { try { // 其实用tryLock方法更严谨些 lock.lock(); while (isFlag()) {// 如果已经存在数据,生产者就等待消费者消费之后再生产。注意多生产者时这里要使用while循环判断。 // 线程等待 conditionProduce.await(); } setName("产品" + (++count)); System.out.println(threadName + "生产者生产--->" + getName()); setFlag(true); conditionConsumer.signal(); } catch (Exception e) { e.printStackTrace(); } finally { // finally代码块通常都是存放资源释放操作的代码 // 不管执行过程发生什么情况都要释放锁资源,否则就会无限期等待下去了。导致程序崩溃 lock.unlock(); } } /** * 消费产品方法 * @param threadName */ public void consumer(String threadName) { try { // 其实用tryLock方法更严谨些 lock.lock(); while (!isFlag()) {// 如果没有数据消费者就等待生产者生产之后再消费,多消费者时这里要使用while循环判断。 conditionConsumer.await(); } System.out.println(threadName + "消费者消费=====》" + getName()); setFlag(false);// 标识已经消费了 conditionProduce.signal(); } catch (Exception e) { e.printStackTrace(); } finally { // finally代码块通常都是存放资源释放操作的代码 // 不管执行过程发生什么情况都要释放锁资源,否则就会无限期等待下去了。导致程序崩溃 lock.unlock(); } }}
ProductThread Code
/*** 生产者对象* @author xuyi3* @2016年4月7日 @下午1:38:16* @ProductThread* @功能说明:生产产品<br>* @春风十里不如你* @备注*/public class ProductThread implements Runnable { // 共享资源对象 private Resource resource; public ProductThread(Resource resource) { this.resource = resource; } @Override public void run() { // 备注:比较优雅的多线程代码,在run()方法体内尽量出现较少的代码,不推荐把同步代码和一些复杂的逻辑放在run()方法体内。 // 因为如果把所有同步代码都放在run()方法体内写的话,非常不好的维护并且代码结构不够清晰。 while (true) { // 生产者生产产品 resource.produce(Thread.currentThread().getName()); } }}
ConsumerThread Code
/*** 消费者对象* @author xuyi3* @2016年4月7日 @下午2:07:22* @ConsumerThread* @功能说明:<br>* @春风十里不如你* @备注*/public class ConsumerThread implements Runnable { // 共享资源Resource对象 private Resource resource; public ConsumerThread(Resource resource) { this.resource = resource; } @Override public void run() { // 备注:比较优雅的多线程代码,在run()方法体内尽量出现较少的代码,不推荐把同步代码和一些复杂的逻辑放在run()方法体内。 // 因为如果把所有同步代码都放在run()方法体内写的话,非常不好的维护并且代码结构不够清晰。 while (true) { // 消费者消费产品 resource.consumer(Thread.currentThread().getName()); } }}
AppMain Code
public class AppMain {public static void main(String[] args) { // 共享资源对象 Resource resource = new Resource(); // 创建生产者对象 ProductThread productThread = new ProductThread(resource); // 创建消费者对象 ConsumerThread consumerThread = new ConsumerThread(resource); // 启动两个线程 new Thread(productThread, "生产者1 ").start(); new Thread(consumerThread, "Consumer1").start(); new Thread(productThread, "生产者2 ").start(); new Thread(consumerThread, "Consumer2").start(); }}
总结说明
多个生产者和多个消费者模型实现的关键在于,资源共享(同步同个对象锁)和资源的标识以及等待唤醒机制wait()和notifyAll()方法。但是每次都需要要判断标识符,因此需要使用while而不能试if。JDK1.5之前使用这种方式处理还不错,但是这里有个明显的问题就是,每次都是唤醒所有的线程,并不是只唤醒我们希望唤醒的线程。这是会降低效率的,尤其是在线程数比较多并发量比较高的时候,就会显得性能并不高。本章使用JDK1.5之后的并发包下的Lock和Condition来高效解决这个问题,关于Lock和Condition的介绍可以参考java doc或Java 理论与实践: JDK 5.0 中更灵活、更具可伸缩性的锁定机制
0 0
- 生产者消费者模型(多个生产者和多个消费者)JDK1.5 (Lock&Condition)实现版
- 生产者消费者模型(多个生产者和多个消费者)JDK1.5之前实现版
- 使用Lock和Condition实现生产者消费者模型
- Java多线程 多个生产者和多个消费者实现同步 jdk1.5
- Java多线程 多个生产者和多个消费者实现同步 jdk1.4
- 使用 Lock 与Condition 实现生产者消费者
- 使用lock&condition实现生产者消费者
- 使用Lock的Condition实现生产者消费者
- 使用jdk1.5的多线程 lock condition 实现方式实现 生产者消费者问题
- 使用Lock和Condition实现生产者和消费者
- java多线程之多生产者与多消费者案例之Lock和Condition实现方式
- 使用ReentrantLock和Condition实现生产者消费者模型
- 多生产者多消费者问题(Lock接口、Condition接口)
- 多个生产者,多个消费者
- 黑马程序员——多个生产者,多个消费者 signalAll() JDK1.5线程新特性
- JAVA 线程通信以及多个生产者消费者模型
- 生产者消费者模型--修改多个线程的情况
- 利用Condition实现生产者和消费者资源共享
- Linux ipcs --显示进程间通信设施状态
- react-native 打离线包
- iOS开发的交互界面的搭建选择
- Java访问https接口实现
- CMD编译JNI头文件方法 jobject/jclass 参数
- 生产者消费者模型(多个生产者和多个消费者)JDK1.5 (Lock&Condition)实现版
- 装修选门技巧
- 《平凡的世界》读后感
- Nginx 开启http目录下载
- Linux jar --jar包打包工具
- Action的深入分析及ActionMapping的测试
- ubuntu16.04和windows双系统解决时间不一致
- IP地址分类、子网掩码、私有地址区别
- 分治法---二分搜索技术