三种实现方式:

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. Objective-C代码学习大纲(4)

    2011-05-11 14:06 佚名 otierney 字号:T | T 本文为台湾出版的<Objective-C学习大纲>的翻译文档,系统介绍了Objective-C代码,很多名词为台 ...

  2. 利用脚手架vue cli搭建vue项目

    vue.js https://vuejs.org/ 基础: http://cn.vuejs.org/v2/guide/installation.html 1.安装需要利用npm包管理器,所以首先安装n ...

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

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

  4. HDU 1866 A + B forever!

    A + B forever! Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) T ...

  5. .net core 启动域名及端口配置

    前两天转载一篇.net core 启动分析,由于发布时候一直纠结在默认5000端口上,所以好好研究了一下. 1.IIS集成 如果通过IIS当宿主的话,那这些都不是事情,强大的IIS可以帮助我们对站点的 ...

  6. 4.2 - MySQL

    一.表关系 请创建如下表,并创建相关约束 班级表:class 学生表:student cid caption grade_id sid sname gender class_id 1 一年一班 1 1 ...

  7. leetcode 去除单链表倒数第k个节点

    Given a linked list, remove the n-th node from the end of list and return its head. Example: Given l ...

  8. Buns---cf 106C(多重背包)

    题目链接:http://codeforces.com/problemset/problem/106/C 题意:有n克面粉,m种馅料,然后每种馅料有ai克,bi克馅料和ci克面粉做的面包可以买di元,也 ...

  9. 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活--hdu2191(多重背包模板)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2191 标准的多重背包 题目 有N种物品和一个容量为V的背包.第i种物品最多有n[i]件可用,每件费用是 ...

  10. Design Patterns Example Code (in C++)

    Overview Design patterns are ways to reuse design solutions that other software developers have crea ...