三种实现方式:

1. Object对象的wait(),notify(),加synchronize.

2. Lock的await(),signal().

3. BlockingQueue阻塞队列.

Object对象的wait(),notify(),加synchronize --> StorageObject();

Lock的await(),signal() --> StorageLock();

BlockingQueue阻塞队列 --> StorageBlockingQueue();

package concurent;

import java.util.LinkedList;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; /**
* Created by jenkin K on 17/6/8.
*/
public class PCModelTread { public static void main(String args[]){ // Storage storage = new StorageObject();
Storage storage = new StorageLock();
// Storage storage = new StorageBlockingQueue(); Producer p1 = new Producer(storage);
Producer p2 = new Producer(storage);
Producer p3 = new Producer(storage);
Producer p4 = new Producer(storage); Consumer c1 = new Consumer(storage);
Consumer c2 = new Consumer(storage); p1.setNum(6);
p2.setNum(1);
p3.setNum(1);
p4.setNum(8); c1.setNum(1);
c2.setNum(5); new Thread(p1, "producer1").start();
new Thread(p2, "producer2").start();
new Thread(p3, "producer3").start();
new Thread(p4, "producer4").start(); new Thread(c1, "consumer1").start();
new Thread(c2, "consumer2").start();
}
} interface Storage {
public void consume(int num);
public void produce(int num);
} class StorageObject implements Storage {
final int MAX_STORAGE = 10;
private LinkedList<Object> list = new LinkedList<Object>(); public void produce(int num){
synchronized (list){
while(num + list.size() > MAX_STORAGE){
System.out.println("库存:["+ list.size() + "]/["+ MAX_STORAGE +"], 待生产数量:[" + num + "], 生产阻塞:" + Thread.currentThread().getName() + "阻塞.");
try{
list.wait();
}catch (InterruptedException e){
e.printStackTrace();
}
}
for(int i = 0; i < num; i++){
list.add(new Object());
System.out.println("库存:["+ list.size() + "]/[" + MAX_STORAGE + "], " + Thread.currentThread().getName() + "正在生产:[" + (i+1) + "].");
}
System.out.println(Thread.currentThread().getName() + "生产完成, 共生产:" + num + ", 库存:["+ list.size() + "]/["+ MAX_STORAGE +"].");
list.notifyAll();
}
} public void consume(int num){
synchronized (list){
while(list.size() < num){
System.out.println("库存:["+ list.size() + "]/[" + MAX_STORAGE + "], 待消费数量:[" + num + "], 消费阻塞:" + Thread.currentThread().getName() + "阻塞.");
try{
list.wait();
}catch (InterruptedException e){
e.printStackTrace();
}
}
for(int i = 0; i < num; i++){
System.out.println("库存:["+ list.size() + "]/[" + MAX_STORAGE + "], " + Thread.currentThread().getName() + "正在消费:[" + (i+1) + "].");
list.remove();
}
System.out.println(Thread.currentThread().getName() + "消费完成, 共消费:" + num + ", 库存:["+ list.size() + "]/["+ MAX_STORAGE + "].");
list.notifyAll();
}
}
} class StorageLock implements Storage {
final int MAX_STORAGE = 10;
LinkedList<Object> list = new LinkedList<Object>();
Lock lock = new ReentrantLock(false);
Condition produce = lock.newCondition();
Condition consume = lock.newCondition(); @Override
public void produce(int num) {
lock.lock();
try {
while (num + list.size() > MAX_STORAGE) {
System.out.println("库存:[" + list.size() + "]/[" + MAX_STORAGE + "], 待生产数量:[" + num + "], 生产阻塞:" + Thread.currentThread().getName() + "阻塞.");
produce.await();
}
for (int i = 0; i < num; i++) {
list.add(new Object());
System.out.println("库存:[" + list.size() + "]/[" + MAX_STORAGE + "], " + Thread.currentThread().getName() + "正在生产:[" + (i + 1) + "].");
}
System.out.println(Thread.currentThread().getName() + "生产完成, 共生产:" + num + ", 库存:[" + list.size() + "]/[" + MAX_STORAGE + "].");
}catch (InterruptedException e){
e.printStackTrace();
}finally {
produce.signalAll();
consume.signalAll();
lock.unlock();
}
} @Override
public void consume(int num) {
lock.lock();
try {
while (list.size() < num) {
System.out.println("库存:[" + list.size() + "]/[" + MAX_STORAGE + "], 待消费数量:[" + num + "], 消费阻塞:" + Thread.currentThread().getName() + "阻塞.");
consume.await();
}
for (int i = 0; i < num; i++) {
System.out.println("库存:[" + list.size() + "]/[" + MAX_STORAGE + "], " + Thread.currentThread().getName() + "正在消费:[" + (i + 1) + "].");
list.remove();
}
System.out.println(Thread.currentThread().getName() + "消费完成, 共消费:" + num + ", 库存:[" + list.size() + "]/[" + MAX_STORAGE + "].");
}catch (InterruptedException e){
e.printStackTrace();
}finally {
consume.signalAll();
produce.signalAll();
lock.unlock();
}
}
} class StorageBlockingQueue implements Storage{
int MAX_STORAGE = 10;
BlockingQueue<Object> queue = new LinkedBlockingQueue<Object>(MAX_STORAGE); @Override
public void produce(int num) {
if(queue.size() == MAX_STORAGE){
System.out.println("库存:[" + queue.size() + "]/[" + MAX_STORAGE + "], 待生产数量:[" + num + "], 生产阻塞:" + Thread.currentThread().getName() + "阻塞.");
}
for(int i = 0; i < num; i++){
try {
queue.put(new Object());
System.out.println("库存:[" + queue.size() + "]/[" + MAX_STORAGE + "], " + Thread.currentThread().getName() + "正在生产:[" + (i + 1) + "].");
}catch (InterruptedException e){
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + "生产完成, 共生产:" + num + ", 库存:[" + queue.size() + "]/[" + MAX_STORAGE + "].");
} @Override
public void consume(int num) {
if(queue.size() == 0){
System.out.println("库存:[" + queue.size() + "]/[" + MAX_STORAGE + "], 待消费数量:[" + num + "], 消费阻塞:" + Thread.currentThread().getName() + "阻塞.");
}
for (int i = 1; i < num; i++){
try{
queue.take();
System.out.println("库存:[" + queue.size() + "]/[" + MAX_STORAGE + "], " + Thread.currentThread().getName() + "正在消费:[" + (i + 1) + "].");
}catch (InterruptedException e){
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + "消费完成, 共消费:" + num + ", 库存:[" + queue.size() + "]/[" + MAX_STORAGE + "].");
}
} class Producer implements Runnable { Storage storage;
int num; public Producer(Storage storage){
this.storage = storage;
} @Override
public void run() {
produce(num);
} public void produce(int num){
storage.produce(num);
} public void setNum(int num) {
this.num = num;
}
} class Consumer implements Runnable { Storage storage;
int num; public Consumer(Storage storage){
this.storage = storage;
}
@Override
public void run() {
consumer(num);
} public void consumer(int num){
storage.consume(num);
} public void setNum(int num) {
this.num = num;
}
}

输出结果:

StorageObject()输出结果:
库存:[1]/[10], producer1正在生产:[1].
库存:[2]/[10], producer1正在生产:[2].
库存:[3]/[10], producer1正在生产:[3].
库存:[4]/[10], producer1正在生产:[4].
库存:[5]/[10], producer1正在生产:[5].
库存:[6]/[10], producer1正在生产:[6].
producer1生产完成, 共生产:6, 库存:[6]/[10].
库存:[6]/[10], consumer2正在消费:[1].
库存:[5]/[10], consumer2正在消费:[2].
库存:[4]/[10], consumer2正在消费:[3].
库存:[3]/[10], consumer2正在消费:[4].
库存:[2]/[10], consumer2正在消费:[5].
consumer2消费完成, 共消费:5, 库存:[1]/[10].
库存:[1]/[10], consumer1正在消费:[1].
consumer1消费完成, 共消费:1, 库存:[0]/[10].
库存:[1]/[10], producer4正在生产:[1].
库存:[2]/[10], producer4正在生产:[2].
库存:[3]/[10], producer4正在生产:[3].
库存:[4]/[10], producer4正在生产:[4].
库存:[5]/[10], producer4正在生产:[5].
库存:[6]/[10], producer4正在生产:[6].
库存:[7]/[10], producer4正在生产:[7].
库存:[8]/[10], producer4正在生产:[8].
producer4生产完成, 共生产:8, 库存:[8]/[10].
库存:[9]/[10], producer3正在生产:[1].
producer3生产完成, 共生产:1, 库存:[9]/[10].
库存:[10]/[10], producer2正在生产:[1].
producer2生产完成, 共生产:1, 库存:[10]/[10]. StorageLock()输出结果:
库存:[1]/[10], producer1正在生产:[1].
库存:[2]/[10], producer1正在生产:[2].
库存:[3]/[10], producer1正在生产:[3].
库存:[4]/[10], producer1正在生产:[4].
库存:[5]/[10], producer1正在生产:[5].
库存:[6]/[10], producer1正在生产:[6].
producer1生产完成, 共生产:6, 库存:[6]/[10].
库存:[7]/[10], producer2正在生产:[1].
producer2生产完成, 共生产:1, 库存:[7]/[10].
库存:[8]/[10], producer3正在生产:[1].
producer3生产完成, 共生产:1, 库存:[8]/[10].
库存:[8]/[10], 待生产数量:[8], 生产阻塞:producer4阻塞.
库存:[8]/[10], consumer1正在消费:[1].
consumer1消费完成, 共消费:1, 库存:[7]/[10].
库存:[7]/[10], consumer2正在消费:[1].
库存:[6]/[10], consumer2正在消费:[2].
库存:[5]/[10], consumer2正在消费:[3].
库存:[4]/[10], consumer2正在消费:[4].
库存:[3]/[10], consumer2正在消费:[5].
consumer2消费完成, 共消费:5, 库存:[2]/[10].
库存:[3]/[10], producer4正在生产:[1].
库存:[4]/[10], producer4正在生产:[2].
库存:[5]/[10], producer4正在生产:[3].
库存:[6]/[10], producer4正在生产:[4].
库存:[7]/[10], producer4正在生产:[5].
库存:[8]/[10], producer4正在生产:[6].
库存:[9]/[10], producer4正在生产:[7].
库存:[10]/[10], producer4正在生产:[8].
producer4生产完成, 共生产:8, 库存:[10]/[10]. StorageBlockingQueue()输出结果:
库存:[3]/[10], producer2正在生产:[1].
库存:[3]/[10], consumer2正在消费:[2].
库存:[4]/[10], producer4正在生产:[1].
consumer1消费完成, 共消费:1, 库存:[4]/[10].
库存:[3]/[10], producer3正在生产:[1].
producer3生产完成, 共生产:1, 库存:[3]/[10].
库存:[2]/[10], producer1正在生产:[1].
库存:[3]/[10], producer4正在生产:[2].
库存:[2]/[10], consumer2正在消费:[3].
producer2生产完成, 共生产:1, 库存:[3]/[10].
库存:[4]/[10], consumer2正在消费:[4].
库存:[5]/[10], producer4正在生产:[3].
库存:[4]/[10], producer1正在生产:[2].
库存:[5]/[10], producer1正在生产:[3].
库存:[4]/[10], producer4正在生产:[4].
库存:[3]/[10], consumer2正在消费:[5].
库存:[7]/[10], producer4正在生产:[5].
库存:[6]/[10], producer1正在生产:[4].
库存:[8]/[10], producer4正在生产:[6].
consumer2消费完成, 共消费:5, 库存:[7]/[10].
库存:[10]/[10], producer4正在生产:[7].
库存:[9]/[10], producer1正在生产:[5].

  

从输出结果看,Synchronized和Lock方式,生产和消费是有序的,也就是某一生产线程全生产完,才会释放锁,不会被其他线程强占。BlockingQueue方式,生产和消费是无序的,即,生产线程没有生产完,或是消费线程没有消费完,都会被其他线程强占。原因是,前者的循环生产操作是在锁同步块里边,后者的生产循环生产操作是在锁的外面。

生产者消费者JAVA实现的更多相关文章

  1. 经典线程同步问题(生产者&消费者)--Java实现

    生产者-消费者(producer-consumer)问题是一个著名的线程同步问题.它描述的是:有一群生产者线程在生产产品,并将这些产品提供给消费者线程去消费. 为使生产者与消费者之间能够并发执行,在两 ...

  2. 生产者消费者-Java代码实现

    import java.util.LinkedList; class Storage{ private static final int MAX = 100; LinkedList<Object ...

  3. 生产者消费者 java.util.concurrent.lock包

    package com.mozq.thread.producer2; import java.util.concurrent.locks.Condition; import java.util.con ...

  4. 生产者消费者问题Java三种实现

    生产者-消费者Java实现 2017-07-27 1 概述 生产者消费者问题是多线程的一个经典问题,它描述是有一块缓冲区作为仓库,生产者可以将产品放入仓库,消费者则可以从仓库中取走产品. 解决生产者/ ...

  5. 第23章 java线程通信——生产者/消费者模型案例

    第23章 java线程通信--生产者/消费者模型案例 1.案例: package com.rocco; /** * 生产者消费者问题,涉及到几个类 * 第一,这个问题本身就是一个类,即主类 * 第二, ...

  6. Java里的生产者-消费者模型(Producer and Consumer Pattern in Java)

    生产者-消费者模型是多线程问题里面的经典问题,也是面试的常见问题.有如下几个常见的实现方法: 1. wait()/notify() 2. lock & condition 3. Blockin ...

  7. Java数据结构之队列的实现以及队列的应用之----简单生产者消费者应用

    Java数据结构之---Queue队列 队列(简称作队,Queue)也是一种特殊的线性表,队列的数据元素以及数据元素间的逻辑关系和线性表完全相同,其差别是线性表允许在任意位置插入和删除,而队列只允许在 ...

  8. Java多线程之并发协作生产者消费者设计模式

    两个线程一个生产者个一个消费者 需求情景 两个线程,一个负责生产,一个负责消费,生产者生产一个,消费者消费一个 涉及问题 同步问题:如何保证同一资源被多个线程并发访问时的完整性.常用的同步方法是采用标 ...

  9. Java多线程15:Queue、BlockingQueue以及利用BlockingQueue实现生产者/消费者模型

    Queue是什么 队列,是一种数据结构.除了优先级队列和LIFO队列外,队列都是以FIFO(先进先出)的方式对各个元素进行排序的.无论使用哪种排序方式,队列的头都是调用remove()或poll()移 ...

随机推荐

  1. 合并图片、EUI顺序、CacheAsBitmap对drawcall影响的测试

    一 什么是DrawCall Draw Call 理解和优化: http://blog.csdn.net/sakyaer/article/details/44459881 draw call是openG ...

  2. MFC中控件的TAB顺序

    本文来自: http://hi.baidu.com/qingcaichongch/item/47f7ae14de8cbef6ddeeca42 在MFC中添加控件后,按Ctrl+d可以改变控件TAB顺序 ...

  3. [移动云计算开发 01] 解决 windows 7 安装设置 nginx 出现端口占用的问题

    一开始 到nginx官网 http://nginx.org/en/download.html 下载 1.4.2版本,解压安装到自己希望设置的文件夹即可, 但是打开localhost却出现了 “NOT ...

  4. 虚拟机VMWare安装苹果系统MacOS详细教程(联网设置,全屏插件、文件互传)

    运行环境: VMware® Workstation 12 Pro(自行安装,或者用这个) 推荐(下面以10.11.6版本做的教程,但是安装时推荐使用此版本安装然后升级到10.11.6):MacOS X ...

  5. CodeForces 639 A

    Bear and Displayed Friends time limit per test2 seconds memory limit per test256 megabytes inputstan ...

  6. 安装串口设备驱动时遇到 Windows 无法验证此设备所需的驱动程序的数字签名。最近的硬件或软件更改安装的文件可能未正确签名或已损坏,或者可能是来自未知来源的恶意软件. 问题该如何处理?

    win7 系统直接在 cmd 命令行中输入以下语句,重启电脑后重新安装驱动即可. BCDEDIT -SET LOADOPTIONS DISABLE_INTEGRITY_CHECKS BCDEDIT - ...

  7. javaweb前后台中文参数乱码

    一.描述 从前台传中文参数到后台,发现中文乱码. 二.解决 首先,统一所有文件为utf-8格式. 其次,在传参时,使用js的encodeURI函数,对参数进行编码. 然后一定要对该中文参数进行两次编码 ...

  8. pandas_datareader.data 和 fix_yahoo_finance 获取金融数据

    参考:https://zhuanlan.zhihu.com/p/35360694 1.获取数据 #定义所需要的数据 gafataDict={"谷歌":"GOOG" ...

  9. B. Mike and Fun---cf548B(暴力求解)

    题目链接:http://codeforces.com/problemset/problem/548/B 有一个n*m的矩阵,里面只有0和1,现在有Q个改变,每次都把(x,y)这点变为相反的点(0变1, ...

  10. Linux cp命令

    cp命令(copy),用来对一个或多个文件,目录进行拷贝 1.语法 cp [选项] [参数] 2.命令选项 -b 当文件存在时,覆盖前,为其创建一个备份-d 当复制软连接时,把目标文件或目录也建立为软 ...