三种实现方式:

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. jfinal如何调用存储过程?

    存储过程用一下 Db.execute(ICallback) 这个方法,在其中用一下:connection.prepareCall(sql).execute();就可以调用存储过程了,并且还可以自由控制 ...

  2. Angular2+学习第2篇 cli 环境搭建过程

    Angular-cli是angular团队针对Angular2提供的脚手架,用于环境搭建,运行等:具体参考Angular-cli GitHub Angular的启动过程,需要先回答三个问题: 启动时加 ...

  3. PHP array_merge() 函数

    <?php $a1=array("a"=>"red","b"=>"green"); $a2=array ...

  4. No Feign Client for loadBalancing defined. Did you forget to include spring-cloud-starter-netflix-ribbon?

    ... 60 common frames omittedCaused by: java.lang.IllegalStateException: No Feign Client for loadBala ...

  5. Pulsar

    The Apache Software Foundation Announces Apache® Pulsar™ as a Top-Level Project : The Apache Softwar ...

  6. Enables DNS lookups on client IP addresses

    w虚拟域名访问,路由可以到达,但无输出. http://httpd.apache.org/docs/2.2/mod/core.html#hostnamelookups

  7. authz_core_module

    w https://httpd.apache.org/docs/trunk/mod/mod_authz_core.html codeigniter index.html .htaccess <I ...

  8. 用flask开发个人博客(4)—— flask中4种全局变量

    https://blog.csdn.net/hyman_c/article/details/53512109 一  current_app current_app代表当前的flask程序实例,使用时需 ...

  9. datetime 模块详解 -- 基本的日期和时间类型

    转自:https://www.cnblogs.com/fclbky/articles/4098204.html datetime 模块提供了各种类用于操作日期和时间,该模块侧重于高效率的格式化输出 在 ...

  10. 荣誉墙项目day26 django 项目路由配置

    项目路由配置文件包括:配置目录里的urls.py文件和各个app目录里的urls.py文件 1.include()——从项目主路由分配到各APP主路由 from django.conf.urls im ...