Lock锁实现生产者消费者及Condition 精准的通知和唤醒线程

Lock锁实现生产者消费者及Condition 精准的通知和唤醒线程

Synchronized实现时用wait()方法等待和notify()唤醒。

Lock锁用的是Condtion对象的await()方法等待和signal()唤醒。

Lock锁实现生产者消费者问题
public class ProAndConByLock1 {
    public static void main(String[] args) {
        Data1 data1 = new Data1();
        /* ()->{}: lambda表达式 (参数)->{ 代码 } 就是下面的:
                    new Runnable() {
                      @Override
                      public void run() {}
        */
      new Thread(()->{ for (int i = 0; i < 5; i++) data1.increment();},"Pro").start(); // 生产者线程
      new Thread(()->{ for (int i = 0; i < 5; i++) data1.decrement();},"Con").start(); // 消费者线程
    }
}


// 资源类
class Data1{
    private int num=0;
    private Lock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();

    public  void increment(){ // 生产+1
        // 加锁
        lock.lock();
        try {
            while (num!=0){
                condition.await(); // 等待
            }
            num++;
            System.out.println(Thread.currentThread().getName()+"执行了; num="+num);
            // 唤醒所有等待的线程
            condition.signalAll();

        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock(); // 解锁
        }
    }

    public void decrement(){ // 消费-1
        // 加锁
        lock.lock();
        try {
            while (num!=1){
                condition.await(); // 等待
            }
            num--;
            System.out.println(Thread.currentThread().getName()+"执行了; num="+num);
            // 唤醒所有等待的线程
            condition.signalAll();

        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock(); // 解锁
        }
    }
}

image-20220512223200702

Condition 精准的通知和唤醒线程

要求线程执行顺序 : A线程执行 --> B线程执行 --> C线程执行

public class ProAndConByLock {
    public static void main(String[] args) {
        Data data = new Data();
        /* ()->{}: lambda表达式 (参数)->{ 代码 } 就是下面的:
                    new Runnable() {
                      @Override
                      public void run() {}
        */
        
        // 要求线程执行顺序 : A线程执行 --> B线程执行 --> C线程执行
        new Thread(()->{ for (int i = 0; i < 5; i++) data.a(); },"A").start();
        new Thread(()->{ for (int i = 0; i < 5; i++) data.b(); },"B").start();
        new Thread(()->{ for (int i = 0; i < 5; i++) data.c(); },"C").start();
    }
}


// 资源类
class Data{
    private int num=1; // num=1 唤醒A线程 ,num=2 唤醒B线程 ,num=3 唤醒C线程
    private Lock lock = new ReentrantLock();

    // 如果A线程condition1.await(); 等待 。 那么 condition1.signal(); 唤醒的就是指定的A线程
    private Condition condition1 = lock.newCondition();
    private Condition condition2 = lock.newCondition();
    private Condition condition3 = lock.newCondition();

    public  void a(){
        // 加锁
        lock.lock();
        try {
            while (num!=1){ // while判断防止虚假唤醒
                condition1.await(); // 等待
            }
            System.out.println(Thread.currentThread().getName()+"执行了; num="+num);
            num=2;
            // 唤醒
            condition2.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock(); // 解锁
        }
    }

    public void b(){
        // 加锁
        lock.lock();
        try {
            while (num!=2){
                condition2.await(); // 等待
            }
            System.out.println(Thread.currentThread().getName()+"执行了; num="+num);
            num=3;
            // 唤醒
            condition3.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock(); // 解锁
        }
    }

    public void c(){
        // 加锁
        lock.lock();
        try {
            while (num!=3){
                condition3.await(); // 等待
            }
            System.out.println(Thread.currentThread().getName()+"执行了; num="+num);
            num=1;
            // 唤醒
            condition1.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock(); // 解锁
        }
    }
}

结果:按照 A线程 --> B线程 --> C线程 顺序执行

image-20220512220922743

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值