多线程之生产消费者【经典例子java】
来源:互联网 发布:2016大数据教程百度云 编辑:程序博客网 时间:2024/05/16 08:03
1.普通的生产消费者例子
synchronized JVM提供的多线程同步,在少量线程下,足够用来
this.wait() 线程等待
notify(), JVM去随机唤醒一个线程,然后拿到锁 【不用竞争】
notifyall() JVM去唤醒所有线程,然后竞争拿到锁【需要竞争】
多线程,小心死锁和没同步住数据
package com.test.thread.producerconsumer;/** * 资源类 * @author 汪兴安 * * * bug 1.synchronized 方法中if this.wait();需要改成while this.wait(); 导致现象:多生产或多消费 * 2.notify(); 必须换成成notifyAll() ,不然会死锁 导致现象:程序无限等待下去 * */public class Resource {// 商品名称private String name;private String names;public String getNames() {return names;}public void setNames(String names) {this.names = names;}// 商品IDprivate int id = 1;// 是否有商品private boolean hasGoods = false;public String getName() {return name;}public void setName(String name) {this.name = name;}// 生产方法public synchronized void set(String name) {// 有商品while (hasGoods) { //if 多线程用if,判断是作死try {//等等,已经有商品了,当然可以休息下this.wait();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}this.setName(name + "_" + id);id++;System.out.println("生产名称:" + Thread.currentThread().getName()+ "以生产商品为:" + this.name);// 有商品hasGoods = true;// 想通知消费线程来消费notifyAll();// 2.notify(); 必须换成成notifyAll() ,不然会死锁}// 消费方法public synchronized void out() {// 没商品while (!hasGoods) {//if 多线程用if,判断是作死 应该放在while里面,因为如果是if的话,当被唤醒了,直接在if里面,往下执行了try {// 等等this.wait();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}System.out.println("消费名称:" + Thread.currentThread().getName()+ "以消费商品为:" + this.name);// 无商品hasGoods = false;// 想通知生产线程来消费notifyAll();// 2.notify(); 必须换成成notifyAll() ,不然会死锁}}
package com.test.thread.producerconsumer;/** * 生产者 线程 * @author 汪兴安 * */public class Producter implements Runnable {//持有对方的引用private Resource resource;public Producter(Resource resource){this.resource=resource;}public void run(){//不断生产while(true){resource.set(resource.getNames());}}}
package com.test.thread.producerconsumer;/** * 不断去消费 线程 * @author 汪兴安 * */public class Customer implements Runnable {//持有对方的引用private Resource resource;public Customer(Resource resource){this.resource=resource;}public void run(){//不断消费while(true){resource.out();}}}
package com.test.thread.producerconsumer;/** * 多线程,就是要模拟多个请求才行 * @author 汪兴安 * */public class Test {public static void main(String[] args) {// TODO Auto-generated method stubResource resource=new Resource();resource.setNames("iphone");Producter p=new Producter(resource);Customer c=new Customer(resource);new Thread(p).start();//一个工厂 生产new Thread(c).start(); //一群消费者new Thread(c).start();new Thread(c).start();new Thread(c).start();new Thread(c).start();new Thread(c).start();}}
===================================华丽的分开了==============================================================================
其他类不变,就Resource变了,注释非常多,自己体会去吧
package com.test.thread.producerconsumer.lock;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;import java.util.concurrent.locks.Condition;/** * 资源类 * * @author 汪兴安 * * Lock 优点:1.显示化,结构灵活,控制细粒度高,可以更高效 * * * * synchronized的wait,nofity,notify是一套的,但Lock与condition可以组合多个,类似2分法,效率大大的提高 * * bug 1.synchronized 方法中if this.wait();需要改成while this.wait(); * 导致现象:多生产或多消费 2.notify(); 必须换成成notifyAll() ,不然会死锁 导致现象:程序无限等待下去 * */public class Resource {// 商品名称private String name;private String names;public String getNames() {return names;}public void setNames(String names) {this.names = names;}// 商品IDprivate int id = 1;// 是否有商品private boolean hasGoods = false;public String getName() {return name;}public void setName(String name) {this.name = name;}// 显示的拿到锁对象private Lock lock = new ReentrantLock();// 获取锁的监控器对象-----更好隔离,拆分更细 与锁lock组合使用private Condition condition = lock.newCondition();// 获取锁的监控器对象-----更好隔离,拆分更细 与锁lock组合使用private Condition conditionOut = lock.newCondition();// 生产方法public void set(String name) {lock.lock();// 获取锁try {// 有商品while (hasGoods) { // if 多线程用if,判断是作死try {// 等等,已经有商品了,当然可以休息下// this.wait();condition.await();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}this.setName(name + "_" + id);id++;System.out.println("生产名称:" + Thread.currentThread().getName()+ "以生产商品为:" + this.name);// 有商品hasGoods = true;// 想通知消费线程来消费// notifyAll();// 2.notify(); 必须换成成notifyAll() ,不然会死锁conditionOut.signalAll();} finally {lock.unlock();}}// 消费方法public void out() {lock.lock();// 获取锁try {// 没商品while (!hasGoods) {// if 多线程用if,判断是作死// 应该放在while里面,因为如果是if的话,当被唤醒了,直接在if里面,往下执行了try {// 等等// this.wait();conditionOut.await();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}System.out.println("消费名称:" + Thread.currentThread().getName()+ "以消费商品为:" + this.name);// 无商品hasGoods = false;// 想通知生产线程来消费// notifyAll();// 2.notify(); 必须换成成notifyAll() ,不然会死锁condition.signalAll();} finally {lock.unlock();}}}
阅读全文
0 0
- 多线程之生产消费者【经典例子java】
- Java多线程-生产消费者2
- java线程:并发协作的经典之生产消费者模型
- Java多线程:“基础篇”11之生产消费者问题
- Java多线程:“基础篇”11之生产消费者问题(2)
- Java多线程系列--“基础篇”11之 生产消费者问题
- Java多线程系列--“基础篇”11之 生产消费者问题
- Java多线程系列--“基础篇”11之 生产消费者问题
- Java多线程系列--“基础篇”11之 生产消费者问题
- java多线程之生产者消费者经典问题
- java多线程之生产者消费者经典问题
- java多线程之生产者消费者经典问题
- java多线程之生产者消费者经典问题
- java多线程之生产者消费者经典问题
- java多线程之生产者消费者经典问题
- java多线程之生产者消费者经典问题
- java多线程之生产者消费者经典问题
- java多线程之生产者消费者经典问题
- 开发者自述:我是怎样理解支持向量机(SVM)与神经网络的
- java笔记 多态
- JS作用域的比较
- js文件在导入时出现错误的解决办法
- 【XML开发】(1)通过"文档类型定义(DTD)"来定义XML标记语言
- 多线程之生产消费者【经典例子java】
- USACO之Section1.1.4 Broken Necklace
- [leetcode] LeetCode周练Contest-34代码解析
- android studio安装文件夹记录
- [VC网络编程笔记-使用API函数操作互斥对象实现线程同步
- 对象的内存布局与锁类型
- 1062. 最简分数(20)
- java打印图形
- Android设置标题栏透明