三种实现方式:

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. LeetCode 笔记系列一 Median of Two Sorted Arrays

    题目:There are two sorted arrays A and B of size m and n respectively. Find the median of the two sort ...

  2. 160606、springmvc中使用Spring Mobile

    springmobile特点: 1.客户端设备识别:识别结果只有3种类型:NORMAL(非手机设备).MOBILE(手机设备).TABLET(平板电脑). 2.网站偏好设置:Spring 通过设备识别 ...

  3. Spoken English Practice(1、This is between you and me, Don't let it out. 2、Don't let your dreams be dreams, no matter how hard it gets, say to yourself, I'm going to make it.)

    绿色:连读:                  红色:略读:               蓝色:浊化:               橙色:弱读     下划线_为浊化 口语蜕变(2017/7/12) ...

  4. 百度jQuery库

    <script src="http://apps.bdimg.com/libs/jquery/1.11.1/jquery.js"></script>

  5. INFORMATION_SCHEMA.STATISTICS 统计 表 库 大小

    INFORMATION_SCHEMA MySQL :: MySQL 5.5 Reference Manual :: 21 INFORMATION_SCHEMA Tables https://dev.m ...

  6. Windows 下配置 php_imagick 扩展

    1.首先按装 imageimagick 可以去 http://imagemagick.org/script/binary-releases.php#windows 这里下载,看好自己的系统环境和选择好 ...

  7. What’s wrong with virtual methods called through an interface

    May 31, 2016 Calling a virtual method through an interface always was a lot slower than calling a st ...

  8. 【非root用户】安装【python,pip,package】

    安装python: 下载源码 解压 进入 ./configure --prefix=/path/python3.6 注意一定要设置prefix,否则默认安装到/usr/local make make ...

  9. 前端 javascript 变量

    变量: python: name = 'alex' JavaScript: name = 'alex' # 全局变量 声明var var name = 'eric' # 局部变量 写全局变量基本好少J ...

  10. mysql构建一张百万级别数据的表信息测试

    表信息: CREATE TABLE dept( /*部门表*/ deptno MEDIUMINT UNSIGNED NOT NULL DEFAULT 0, /*编号*/ dname VARCHAR(2 ...