JUC生产者消费者问题

juc版本和synchronized版本的区别:
在这里插入图片描述
juc这里使用锁需要事先在类里面声明锁,然后用锁获取newCondition,使用condition类即可,以下是jdk,api里面写的

例如,假设我们有一个有限的缓冲区,它支持put和take方法。 如果在一个空的缓冲区尝试一个take ,则线程将阻塞直到一个项目可用; 如果put试图在一个完整的缓冲区,那么线程将阻塞,直到空间变得可用。 我们希望在单独的等待集中等待put线程和take线程,以便我们可以在缓冲区中的项目或空间可用的时候使用仅通知单个线程的优化。 这可以使用两个Condition实例来实现。 

  class BoundedBuffer {
   final Lock lock = new ReentrantLock();
   final Condition notFull  = lock.newCondition(); 
   final Condition notEmpty = lock.newCondition(); 

   final Object[] items = new Object[100];
   int putptr, takeptr, count;

   public void put(Object x) throws InterruptedException {
     lock.lock(); try {
       while (count == items.length)
         notFull.await();
       items[putptr] = x;
       if (++putptr == items.length) putptr = 0;
       ++count;
       notEmpty.signal();
     } finally { lock.unlock(); }
   }

   public Object take() throws InterruptedException {
     lock.lock(); try {
       while (count == 0)
         notEmpty.await();
       Object x = items[takeptr];
       if (++takeptr == items.length) takeptr = 0;
       --count;
       notFull.signal();
       return x;
     } finally { lock.unlock(); }
   }
 } 

模仿它,我们也来写一个自己的生产者和消费者:

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

//线程之间的通信问题:生产者和消费者问题!等待唤醒,通知唤醒线程交替执行A B操作同一个变量num = 0
//        A  num+1
//        B  num-1
public class B {
    public static void main(String[] args) {
        Data2 data=new Data2();

        new Thread(()->{
            for (int i = 0; i <10 ; i++) {
                try {
                    data.product();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"A").start();


        new Thread(()->{
            for (int i = 0; i <10 ; i++) {
                try {
                    data.consumer();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"B").start();


        new Thread(()->{
            for (int i = 0; i <10 ; i++) {
                try {
                    data.product();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"C").start();


        new Thread(()->{
            for (int i = 0; i <10 ; i++) {
                try {
                    data.consumer();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"D").start();

    }
}

class Data2{
    private int num=0;
    Lock lock =new ReentrantLock();
    Condition condition = lock.newCondition();
    public  void product() throws InterruptedException {
        lock.lock();
        try {
            while (num != 0) {
            condition.await();
            }
            num++;
            System.out.println(Thread.currentThread()+"线程生产了1份,当前:"+num);
            condition.signalAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }

    }

    public  void consumer() throws InterruptedException {
//        假如存在虚假唤醒,那么此时的num==0,就进入等待,一直等到num不是虚假唤醒而是真实唤醒变成了1
        lock.lock();
        try {
            while (num == 0) {
                condition.await();
            }
            num--;
            System.out.println(Thread.currentThread()+"线程消费了1份,当前:"+num);
            condition.signalAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }


}

执行结果:

 
Thread[A,5,main]线程生产了1,当前:1
Thread[B,5,main]线程消费了1,当前:0
Thread[C,5,main]线程生产了1,当前:1
Thread[B,5,main]线程消费了1,当前:0
Thread[C,5,main]线程生产了1,当前:1
Thread[D,5,main]线程消费了1,当前:0
Thread[C,5,main]线程生产了1,当前:1
Thread[D,5,main]线程消费了1,当前:0
Thread[C,5,main]线程生产了1,当前:1
Thread[D,5,main]线程消费了1,当前:0
Thread[C,5,main]线程生产了1,当前:1
Thread[D,5,main]线程消费了1,当前:0
Thread[C,5,main]线程生产了1,当前:1
Thread[D,5,main]线程消费了1,当前:0
Thread[C,5,main]线程生产了1,当前:1
Thread[D,5,main]线程消费了1,当前:0
Thread[C,5,main]线程生产了1,当前:1
Thread[D,5,main]线程消费了1,当前:0
Thread[C,5,main]线程生产了1,当前:1
Thread[D,5,main]线程消费了1,当前:0
Thread[C,5,main]线程生产了1,当前:1
Thread[D,5,main]线程消费了1,当前:0
Thread[A,5,main]线程生产了1,当前:1
Thread[D,5,main]线程消费了1,当前:0
Thread[A,5,main]线程生产了1,当前:1
Thread[B,5,main]线程消费了1,当前:0
Thread[A,5,main]线程生产了1,当前:1
Thread[B,5,main]线程消费了1,当前:0
Thread[A,5,main]线程生产了1,当前:1
Thread[B,5,main]线程消费了1,当前:0
Thread[A,5,main]线程生产了1,当前:1
Thread[B,5,main]线程消费了1,当前:0
Thread[A,5,main]线程生产了1,当前:1
Thread[B,5,main]线程消费了1,当前:0
Thread[A,5,main]线程生产了1,当前:1
Thread[B,5,main]线程消费了1,当前:0
Thread[A,5,main]线程生产了1,当前:1
Thread[B,5,main]线程消费了1,当前:0
Thread[A,5,main]线程生产了1,当前:1
Thread[B,5,main]线程消费了1,当前:0


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值