java多线程-生产者/消费者模型

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 的优势在哪里

猜你喜欢

转载自blog.csdn.net/makeliwei1/article/details/80965533