Java——Java实现生产者消费者
1、生产/消费者模型
生产/消费者问题是个非常典型的多线程问题,涉及到的对象包括“生产者”、“消费者”、“仓库”和“产品”。他们之间的关系如下:
(01) 生产者仅仅在仓储未满时候生产,仓满则停止生产。
(02) 消费者仅仅在仓储有产品时候才能消费,仓空则等待。
(03) 当消费者发现仓储没产品可消费时候会通知生产者生产。
(04) 生产者在生产出可消费产品时候,应该通知等待的消费者去消费。
2、生产者消费者实现(synchronized )
// Demo1.java
// 仓库
class Depot {
    private int capacity;    // 仓库的容量
    private int size;        // 仓库的实际数量
    public Depot(int capacity) {
        this.capacity = capacity;
        this.size = 0;
    }
    public synchronized void produce(int val) {
        try {
             // left 表示“想要生产的数量”(有可能生产量太多,需多此生产)
            int left = val;
            while (left > 0) {
                // 库存已满时,等待“消费者”消费产品。
                while (size >= capacity)
                    wait();
                // 获取“实际生产的数量”(即库存中新增的数量)
                // 如果“库存”+“想要生产的数量”>“总的容量”,则“实际增量”=“总的容量”-“当前容量”。(此时填满仓库)
                // 否则“实际增量”=“想要生产的数量”
                int inc = (size+left)>capacity ? (capacity-size) : left;
                size += inc;
                left -= inc;
                System.out.printf("%s produce(%3d) --> left=%3d, inc=%3d, size=%3d\n",
                        Thread.currentThread().getName(), val, left, inc, size);
                // 通知“消费者”可以消费了。
                notifyAll();
            }
        } catch (InterruptedException e) {
        }
    } 
    public synchronized void consume(int val) {
        try {
            // left 表示“客户要消费数量”(有可能消费量太大,库存不够,需多此消费)
            int left = val;
            while (left > 0) {
                // 库存为0时,等待“生产者”生产产品。
                while (size <= 0)
                    wait();
                // 获取“实际消费的数量”(即库存中实际减少的数量)
                // 如果“库存”<“客户要消费的数量”,则“实际消费量”=“库存”;
                // 否则,“实际消费量”=“客户要消费的数量”。
                int dec = (size<left) ? size : left;
                size -= dec;
                left -= dec;
                System.out.printf("%s consume(%3d) <-- left=%3d, dec=%3d, size=%3d\n",
                        Thread.currentThread().getName(), val, left, dec, size);
                notifyAll();
            }
        } catch (InterruptedException e) {
        }
    }
    public String toString() {
        return "capacity:"+capacity+", actual size:"+size;
    }
} 
// 生产者
class Producer {
    private Depot depot;
    public Producer(Depot depot) {
        this.depot = depot;
    }
    // 消费产品:新建一个线程向仓库中生产产品。
    public void produce(final int val) {
        new Thread() {
            public void run() {
                depot.produce(val);
            }
        }.start();
    }
}
// 消费者
class Customer {
    private Depot depot;
    public Customer(Depot depot) {
        this.depot = depot;
    }
    // 消费产品:新建一个线程从仓库中消费产品。
    public void consume(final int val) {
        new Thread() {
            public void run() {
                depot.consume(val);
            }
        }.start();
    }
}
public class Demo1 {
    public static void main(String[] args) {
        Depot mDepot = new Depot(100);
        Producer mPro = new Producer(mDepot);
        Customer mCus = new Customer(mDepot);
        mPro.produce(60);
        mPro.produce(120);
        mCus.consume(90);
        mCus.consume(150);
        mPro.produce(110);
    }
}
运行结果
Thread-0 produce( 60) --> left=  0, inc= 60, size= 60
Thread-4 produce(110) --> left= 70, inc= 40, size=100
Thread-2 consume( 90) <-- left=  0, dec= 90, size= 10
Thread-3 consume(150) <-- left=140, dec= 10, size=  0
Thread-1 produce(120) --> left= 20, inc=100, size=100
Thread-3 consume(150) <-- left= 40, dec=100, size=  0
Thread-4 produce(110) --> left=  0, inc= 70, size= 70
Thread-3 consume(150) <-- left=  0, dec= 40, size= 30
Thread-1 produce(120) --> left=  0, inc= 20, size= 50
3、生产者消费者实现(Lock锁)
package Thread;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class Depot{
    private int capacity; //仓库容量
    private int size; //仓库当前产品数量
    private Lock lock; //锁
    private Condition productCondition; //生产条件
    private Condition consumerCondition; //消费条件
    public Depot(int capacity) {
        this.capacity=capacity;
        this.size=0;
        this.lock = new ReentrantLock();
        this.productCondition = this.lock.newCondition();
        this.consumerCondition = this.lock.newCondition();
    }
    //生产商品
    public void produce(int val) {
        lock.lock();
        try {
            int left=val; //left表示需要生产的数量
            while (left > 0) {
                //当库存已满时,则生产者开始等待消费者消费
                while (size == capacity) {
                    productCondition.await();
                }
                int pro= left > (capacity-size) ? (capacity-size) : left;  //如果生产的数量大于仓库容量,则只生产仓库容量这么多
                size += pro;
                left -= pro;
                System.out.printf("%s produce(%3d) --> left=%3d, inc=%3d, size=%3d\n",
                        Thread.currentThread().getName(), val, left, pro, size);
                consumerCondition.signal(); //消费者消费时,发现当仓库产品为零时,此时消费者等待,调用生产者生产,那么生产者生产完成后则需要释放消费者
            }
        }catch (Exception e){
        }finally {
            lock.unlock();
        }
    }
    //消费商品
    public void consume(int val) {
        lock.lock();
        try {
            int left=val; //left表示需要消费的数量
            while (left > 0) {
                while (size == 0) {  //当前商品数量为零时,消费者需要等待
                    consumerCondition.await();
                }
                int cus=left > size? size : left;
                size -= cus;
                left -= cus;
                System.out.printf("%s consume(%3d) <-- left=%3d, dec=%3d, size=%3d\n",
                        Thread.currentThread().getName(), val, left, cus, size);
                productCondition.signal(); //消费者消费完成后,需要释放生产者
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }
}
//生产者
class Producer{
    private Depot depot;
    public Producer(Depot depot) {
        this.depot = depot;
    }
    public void produce(int val){
        new Thread(){
            @Override
            public void run() {
                depot.produce(val);
            }
        }.start();
    }
}
//消费者
class Customer{
    private Depot depot;
    public Customer(Depot depot) {
        this.depot = depot;
    }
    public void consume(int val) {
        new Thread(){
            @Override
            public void run() {
                depot.consume(val);
            }
        }.start();
    }
}
public class LockTest {
    public static void main(String[] args) {
        Depot mDepot = new Depot(100);
        Producer mPro = new Producer(mDepot);
        Customer mCus = new Customer(mDepot);
        mPro.produce(60);
        mPro.produce(120);
        mCus.consume(90);
        mCus.consume(150);
        mPro.produce(110);
    }
}
运行结果
Thread-0 produce( 60) --> left=  0, inc= 60, size= 60
Thread-1 produce(120) --> left= 80, inc= 40, size=100
Thread-2 consume( 90) <-- left=  0, dec= 90, size= 10
Thread-3 consume(150) <-- left=140, dec= 10, size=  0
Thread-4 produce(110) --> left= 10, inc=100, size=100
Thread-3 consume(150) <-- left= 40, dec=100, size=  0
Thread-4 produce(110) --> left=  0, inc= 10, size= 10
Thread-3 consume(150) <-- left= 30, dec= 10, size=  0
Thread-1 produce(120) --> left=  0, inc= 80, size= 80
Thread-3 consume(150) <-- left=  0, dec= 30, size= 50
Java——Java实现生产者消费者的更多相关文章
- 第23章 java线程通信——生产者/消费者模型案例
		第23章 java线程通信--生产者/消费者模型案例 1.案例: package com.rocco; /** * 生产者消费者问题,涉及到几个类 * 第一,这个问题本身就是一个类,即主类 * 第二, ... 
- java多线程解决生产者消费者问题
		import java.util.ArrayList; import java.util.List; /** * Created by ccc on 16-4-27. */ public class ... 
- java+反射+多线程+生产者消费者模式+读取xml(SAX)入数据库mysql-【费元星Q9715234】
		java+反射+多线程+生产者消费者模式+读取xml(SAX)入数据库mysql-[费元星Q9715234] 说明如下,不懂的问题直接我[费元星Q9715234] 1.反射的意义在于不将xml tag ... 
- Java设计模式之生产者消费者模式
		Java设计模式之生产者消费者模式 博客分类: 设计模式 设计模式Java多线程编程thread 转载 对于多线程程序来说,不管任何编程语言,生产者和消费者模型都是最经典的.就像学习每一门编程语言一 ... 
- java多线程模拟生产者消费者问题,公司面试常常问的题。。。
		package com.cn.test3; //java多线程模拟生产者消费者问题 //ProducerConsumer是主类,Producer生产者,Consumer消费者,Product产品 // ... 
- JAVA多线程之生产者 消费者模式 妈妈做面包案例
		创建四个类 1.面包类 锅里只可以放10个面包 ---装面包的容器2.厨房 kitchen 生产面包 和消费面包 最多生产100个面包3.生产者4消费者5.测试类 多线程经典案例 import ja ... 
- Java里的生产者-消费者模型(Producer and Consumer Pattern in Java)
		生产者-消费者模型是多线程问题里面的经典问题,也是面试的常见问题.有如下几个常见的实现方法: 1. wait()/notify() 2. lock & condition 3. Blockin ... 
- Java并发之:生产者消费者问题
		生产者消费者问题是Java并发中的常见问题之一,在实现时,一般可以考虑使用juc包下的BlockingQueue接口,至于具体使用哪个类,则就需要根据具体的使用场景具体分析了.本文主要实现一个生产者消 ... 
- Java多线程同步——生产者消费者问题
		这是马士兵老师的Java视频教程里的一个生产者消费者问题的模型 public class ProduceConsumer{ public static void main(String[] args) ... 
- java模拟实现生产者---消费者问题
		本文章为小编原创,请尊重文章的原创性,转载请注意写明转载来源:http://blog.csdn.net/u012116457 已知技术參数: 生产者消费者问题,描写叙述一组生产者向一组消费者提供产品/ ... 
随机推荐
- FZU 2150
			题目大意:有一个矩阵,"."表示石头,"#",表示小草,有两个人,可以在任意两个位置点燃小草,小草可以上下左右蔓延,蔓延一次的时间为1,问所有蔓延完所有小草所花 ... 
- D. AB-string
			https://codeforces.com/contest/1238/problem/D 题目大意:统计good string的个数,good string的定义,给定的字符串中含有回文段落, 题解 ... 
- E. Max Gcd
			单点时限: 2.0 sec 内存限制: 512 MB 一个数组a,现在你需要删除某一项使得它们的gcd最大,求出这个最大值. 输入格式 第一行输入一个正整数n,表示数组的大小,接下来一行n个数,第i个 ... 
- poi导出word文档,doc和docx
			maven <!-- https://mvnrepository.com/artifact/org.apache.poi/poi --><dependency> <gro ... 
- C#开发BIMFACE系列34 服务端API之模型对比5:获取模型构件对比差异
			系列目录 [已更新最新开发文章,点击查看详细] BIMFACE平台提供了服务端“获取修改构件属性差异”API,其返回的结果也是一个列表,仅针对修改的构件(不包含新增.删除的构件),是指对于一个 ... 
- 2.hover的使用
			1. 自身的hover div :hover{ :hover前要有空格 } 2.hover指向子元素 father:hover .childer { :hover前不能有空格 } 3.ho ... 
- ubuntu搭建vulhub漏洞环境
			0x01 简介 Vulhub是一个面向大众的开源漏洞靶场,无需docker知识,简单执行两条命令即可编译.运行一个完整的漏洞靶场镜像.旨在让漏洞复现变得更加简单,让安全研究者更加专注于漏洞原理本身. ... 
- 从零开始学AB测试:躲坑篇
			AB测试的原理很简单,只用到了最简单的统计假设检验,但表面的简单通常都隐藏着陷阱,这一点没有经过实践的摸爬滚打是不容易看到的,今天我就把前人已经踩过的坑,一共15个,给大家分享一下.在分享之前,大家脑 ... 
- kubernetes的Statefulset介绍
			StatefulSet是一种给Pod提供唯一标志的控制器,他可以保证部署和扩展的顺序. Pod一致性 包含次序(启动和停止次序).网络一致性.此一致性和Pod相关.与被调度到哪个Node节点无关. 稳 ... 
- Linux-监控与安全运维之zabbix
			zabbix: Zabbix是一个开源分布式监控平台,包含诸多监控功能,用于构建一个符合企业级的监控解决方案.软件由开源社区提供开发和维护,遵循GPL协议,可以自由传播和使用,但开发团队提供收费的技术 ... 
