java多线程-生产者/消费者模型
使用synchronized+wait()+notify()/notifyAll()
package java_lang_Object;
import java.util.LinkedList;
/**
* Created by luckyboy on 2018/7/4.
*/
public class ConsumerAndProducer {
public static void main(String[] args){
Storage storage = new Storage();
Producer p1 = new Producer(10,storage);
Producer p2 = new Producer(20,storage);
Producer p3 = new Producer(90,storage);
Consumer c1 = new Consumer(50,storage);
Consumer c2 = new Consumer(30,storage);
Consumer c3 = new Consumer(40,storage);
p1.start();
p2.start();
p3.start();
c1.start();
c2.start();
c3.start();
}
}
//Storage提供consume()和produce()供Consumer和Producer调用
class Storage{
private final int MAX_SIZE = 100;//
private LinkedList<Object> list = new LinkedList<Object>();//
public void produce(int num){
synchronized (list){
//当仓库的剩余容量不足时
while(list.size() + num >MAX_SIZE){
System.out.println(Thread.currentThread().getName()+" 要生产的数量 == "+ num +" 仓库的数量 == "+list.size()+" 不能生产,等待Consumer消费 ");
try{
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for(int i = 1;i <= num;i++){
list.add(new Object());
}
System.out.println(Thread.currentThread().getName()+" 已经生产产品数 == "+ num+" 当前的仓储量为 == "+list.size());
list.notifyAll();
}
}
public void consume(int num){
synchronized (list){
//当仓库的物品剩余容量不足时
while(list.size() - num <0){
System.out.println(Thread.currentThread().getName()+" 要消费的数量 == "+ num +" 仓库的数量 == "+list.size()+" 不能消费,等待Producer生产");
try{
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for(int i = 1;i <= num;i++){
list.remove();
}
System.out.println(Thread.currentThread().getName()+" 已经消费的产品数 == "+ num+" 当前的仓储量为 == "+list.size());
list.notifyAll();
}
}
public LinkedList<Object> getList() {
return list;
}
public void setList(LinkedList<Object> list) {
this.list = list;
}
}
//生产者
class Producer extends Thread {
private int num;
private Storage storage;
public Producer(int num,Storage storage){
this.storage = storage;
this.num = num;
}
public void setNum(int num){
this.num = num;
}
@Override
public void run(){
this.storage.produce(num);
}
}
//消费者
class Consumer extends Thread{
private int num;
private Storage storage;
public Consumer(int num,Storage storage){
this.num = num;
this.storage = storage;
}
@Override
public void run(){
this.storage.consume(this.num);
}
}
输出结果
Thread-1 已经生产产品数 == 20 当前的仓储量为 == 20
Thread-2 要生产的数量 == 90 仓库的数量 == 20 不能生产,等待Consumer消费
Thread-0 已经生产产品数 == 10 当前的仓储量为 == 30
Thread-5 要消费的数量 == 40 仓库的数量 == 30 不能消费,等待Producer生产
Thread-2 要生产的数量 == 90 仓库的数量 == 30 不能生产,等待Consumer消费
Thread-4 已经消费的产品数 == 30 当前的仓储量为 == 0
Thread-3 要消费的数量 == 50 仓库的数量 == 0 不能消费,等待Producer生产
Thread-2 已经生产产品数 == 90 当前的仓储量为 == 90
Thread-5 已经消费的产品数 == 40 当前的仓储量为 == 50
Thread-3 已经消费的产品数 == 50 当前的仓储量为 == 0
使用ReentranLock+Condition
package java_lang_Object;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* Created by luckyboy on 2018/7/9.
*/
public class ConsumerAndProducer_II {
public static void main(String[] args){
Storage_II storage = new Storage_II();
Producer_II producer1 = new Producer_II(storage,50);
Producer_II producer2 = new Producer_II(storage,60);
Producer_II producer3 = new Producer_II(storage,10);
Consumer_II consumer1 = new Consumer_II(storage,10);
Consumer_II consumer2 = new Consumer_II(storage,40);
Consumer_II consumer3 = new Consumer_II(storage,60);
producer1.start();
producer2.start();
producer3.start();
consumer1.start();
consumer2.start();
consumer3.start();
}
}
//仓库提供Consumer和Producer消费和生产的方法
class Storage_II{
private LinkedList<Object> objectList = new LinkedList<Object>();
private final static int CAPACITY = 100;
private Lock lock = new ReentrantLock();
//private Condition condition = lock.newCondition();
private Condition produce_condition = lock.newCondition();
private Condition consume_condition = lock.newCondition();
public void produce(int num){
try{
lock.lock();
while(objectList.size()+num>CAPACITY){
System.out.println(Thread.currentThread().getName()+" 需要生产:"+ num+" 仓库物品当前为 :"+objectList.size() +" 等待消费");
//condition.await();
produce_condition.await();
}
for(int i= 0;i<num;i++){
objectList.add(new Object());
}
System.out.println(Thread.currentThread().getName()+" 生产了: "+num+" 当前仓库物品数量为: "+objectList.size());
//condition.signalAll();
consume_condition.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally{
lock.unlock();
}
}
public void consume(int num){
try{
lock.lock();
while(objectList.size()-num<0){
System.out.println(Thread.currentThread().getName()+" 需要生产:"+ num+" 仓库物品当前为 :"+objectList.size() +" 等待生产");
//condition.await();
consume_condition.await();
}
for(int i = 0;i<num;i++){
objectList.remove();
}
System.out.println(Thread.currentThread().getName()+" 消费了: "+num+"当前仓库物品数量为: "+objectList.size());
//condition.signalAll();
produce_condition.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally{
lock.unlock();
}
}
}
//消费者
class Consumer_II extends Thread{
private int num;
private Storage_II storage;
public Consumer_II(Storage_II storage, int num){
this.storage = storage;
this.num = num;
}
@Override
public void run(){
this.storage.consume(this.num);
}
}
//生产者
class Producer_II extends Thread{
private int num;
private Storage_II storage;
public Producer_II(Storage_II storage,int num){
this.storage = storage;
this.num = num;
}
@Override
public void run(){
this.storage.produce(this.num);
}
}
输出结果
Thread-0 生产了: 50 当前仓库物品数量为: 50
Thread-3 消费了: 10当前仓库物品数量为: 40
Thread-1 生产了: 60 当前仓库物品数量为: 100
Thread-2 需要生产:10 仓库物品当前为 :100 等待消费
Thread-5 消费了: 60当前仓库物品数量为: 40
Thread-4 消费了: 40当前仓库物品数量为: 0
Thread-2 生产了: 10 当前仓库物品数量为: 10
问题
- 我这里使用一个Condition,而不是生产者一个produce_condition,另一个是consume_condition;两种方式都能实现,相较于第二种方式使用两个Condition 的优势在哪里