Lock Condition 和 synchronized 实现生产者消费者问题

第一种: Lock Condition实现生产者和消费者问题:

package eureka.server;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class MyStock {

    private List<String> stock = new ArrayList();

    private int size = 10;

    Lock lock = new ReentrantLock();

    Condition conditionA = lock.newCondition();//生产者条件

    Condition conditionB = lock.newCondition();//消费者条件

    //生产
    public void add() {
        try {
            lock.lock();
            //如果仓库满了
            while (stock.size() > size) {
                System.out.println("当前仓库已满,当前容量=" + stock.size() + ",threadName =" + Thread.currentThread().getName());
                conditionA.await();
            }
            //生产产品
            System.out.println("生产商品start,当前容量=" + stock.size() + ",threadName =" + Thread.currentThread().getName());
            stock.add("product");
            System.out.println("生产商品end,当前容量=" + stock.size() + ",threadName =" + Thread.currentThread().getName());
            //通知消费者
            conditionB.signal();
        } catch (InterruptedException e) {
        } finally {
            lock.unlock();
        }
    }

    public void reduce() {
        try {
            lock.lock();
            while (stock.size() <= 0) {
                System.out.println("当前仓库没有商品,容量=" + stock.size() + ",threadName =" + Thread.currentThread().getName());
                conditionB.await();
            }
            //消费商品
            System.out.println("消费商品start,当前容量=" + stock.size() + ",threadName =" + Thread.currentThread().getName());
            stock.remove(0);
            System.out.println("消费商品end,当前容量=" + stock.size() + ",threadName =" + Thread.currentThread().getName());
            //通知生产者
            conditionA.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }


    public static void main(String[] args) throws InterruptedException {
        MyStock myStock = new MyStock();
        for (int i = 0; i < 5; i++) {
            Thread threadA = new PThread("" + i, myStock);
            Thread threadB = new RThread("" + i, myStock);
            threadB.start();
            threadA.start();

        }
    }
}

//生产者
class PThread extends Thread {

    private MyStock myStock;

    public PThread(String name, MyStock myStock) {
        super(name);
        this.myStock = myStock;
    }

    @Override
    public void run() {
        myStock.add();
    }
}

//消费者
class RThread extends Thread {

    private MyStock myStock;

    public RThread(String name, MyStock myStock) {
        super(name);
        this.myStock = myStock;
    }

    @Override
    public void run() {
        myStock.reduce();
    }
}

第二种:synchronized实现生产者、消费者问题:

package eureka.server;

import java.util.ArrayList;
import java.util.List;

public class MyStock1 {
    private static List<String> stock = new ArrayList<String>();

    private Object lock = new Object();

    private int size = 10;


    //生产产品
    public void add() {
        synchronized (lock) {
                try {
                    while (stock.size() == size) {
                        System.out.println("当前仓库已满,当前容量=" + stock.size() + ",threadName =" + Thread.currentThread().getName());
                        lock.wait();
                    }
                        //生产产品
                        System.out.println("生产商品start,当前容量=" + stock.size() + ",threadName =" + Thread.currentThread().getName());
                        stock.add("product");
                        System.out.println("生产商品end,当前容量=" + stock.size() + ",threadName =" + Thread.currentThread().getName());
                        //通知消费者
                    lock.notifyAll();

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
       }
    }
   //消费产品
    public void reduce() {
        synchronized (lock) {
               try {
                   while (stock.size() == 0) {
                       System.out.println("当前仓库没有商品,容量=" + stock.size() + ",threadName =" + Thread.currentThread().getName());
                       lock.wait();
                   }
                       //消费商品
                       System.out.println("消费商品start,当前容量=" + stock.size() + ",threadName =" + Thread.currentThread().getName());
                       stock.remove(0);
                       System.out.println("消费商品end,当前容量=" + stock.size() + ",threadName =" + Thread.currentThread().getName());
                       //通知生产者
                   lock.notifyAll();
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
           }
    }

    public static void main(String[] args) throws InterruptedException {
        MyStock1 myStock1 = new MyStock1();
            Thread threadA = new ThreadP("aa", myStock1);
            Thread threadB = new ThreadR("bb", myStock1);
            Thread threadC = new ThreadR("cc", myStock1);
            Thread threadD = new ThreadP("dd", myStock1);
            threadB.start();
            threadC.start();
            Thread.sleep(1000);
            threadA.start();
            threadD.start();
    }
}

//生产者
class ThreadP extends Thread {

    private MyStock1 myStock1;

    public ThreadP(String name, MyStock1 myStock1) {
        super(name);
        this.myStock1 = myStock1;
    }

    @Override
    public void run() {
            myStock1.add();

    }
}

//消费者
class ThreadR extends Thread {

    private MyStock1 myStock1;

    public ThreadR(String name, MyStock1 myStock1) {
        super(name);
        this.myStock1 = myStock1;
    }

    @Override
    public void run() {
            myStock1.reduce();
    }
}

特别注意的点:用synchronized实现时,要注意库存的判断条件用while不能用if:

while (stock.size() == size) {
     System.out.println("当前仓库已满,当前容量=" + stock.size() + ",threadName =" + 
     Thread.currentThread().getName());
      lock.wait();
     }

假如说有2个消费者,1个生产者,当生产者生产一个产品后,调用notifyall方法唤醒2个消费者线程,第一个消费者被唤醒消费完这一个产品后,第二个消费者也开始准备消费产品,如果用if判断条件,此时消费者不会做库存判断,直接消费产品,会导致没有产品能够消费的情况,代码会产生数组下标越界的错误,而如果用while判断,则会判断出现在的库存数量为0,会再次进入等待wait的状态;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值