4.3 使用lock的condition实现等待/通知机制

Condition接口

任意一个Java对象,都拥有一组监视器方法(定义在java.lang.Object上),主要包括wait()、wait(long timeout)、notify()以及notifyAll()方法,这些方法与synchronized同步关键字配合,可以实现等待/通知模式。Condition接口也提供了类似Object的监视器方法,与Lock配合可以实现等待/通知模式。

Condition常用方法

方法名称描述
void await() throws InterruptedException

当前线程进入等待,知道被condition.signal()唤醒或者被中断

void awaitUninterruptibly() 当前线程进入等待,能够响应中断

long awaitNanos(long nanosTimeout) thrwos

InterruptedException

1、返回0或者负数,表示超时了

2、正常被唤醒,返回剩余时间

boolean awaitUnitil(Date deadline) throws

InterruptedException

1、如果没有到指定时间就返回通知,返回true

2、倒了指定时间还没有被通知,返回false

void signal()唤醒一个在condition.await()的程序
void signal() 唤醒所有等待在condition上的现成

Condition使用格式

// 等待
lock.lock();
try {
	condition.await();
} finally {
	lock.unlock();
}

// 唤醒
lock.lock();
try {
	condition.signalAll();
} finally {
	lock.unlock();
}

 

备注:我一开始把condition.await();写成了condition.wait();,结果每次执行到这里的时候就会报错,以为是自己锁用错了,搞了半天才发现是少了个a,应该是await(),顿时心都碎了,特此记录,防止有人采坑

具体报错如下:

Exception in thread "Thread-5" java.lang.IllegalMonitorStateException
消费者消费了一个面包:9
消费者消费了一个面包:8
消费者消费了一个面包:7
	at java.lang.Object.wait(Native Method)
	at java.lang.Object.wait(Object.java:502)
消费者消费了一个面包:6
	at cn.enjoyedu.ch4.TestCondition.product(TestCondition.java:24)
	at cn.enjoyedu.ch4.TestCondition.lambda$main$1(TestCondition.java:61)
	at java.lang.Thread.run(Thread.java:748)

示例:消费者生产者机制

public class TestCondition {
    private int count = 0;
    private static final int SUM = 10;
    private Lock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();

    public void product() {
        while (true) {
            lock.lock();
            try {
                while (count >= SUM) {
                    System.out.println("库存满了,等待消费" + count);
                    condition.await();
                }
                count++;
                System.out.println("生产者生产了一个面包:" + count);
                condition.signalAll();
            } catch (InterruptedException e) {
                //e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    }

    public void customer() {
        while (true) {
            lock.lock();
            try {
                while (count <= 0) {
                    System.out.println("库存为零,等待生产:" + count);
                    condition.await();
                }
                count--;
                System.out.println("消费者消费了一个面包:" + count);
                condition.signalAll();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    }

    public static void main(String[] args){
        TestCondition testCondition = new TestCondition();
        for (int i = 0; i < 3; i++) {
            new Thread(() -> testCondition.customer()).start();

            new Thread(() -> testCondition.product()).start();
        }
    }
}

结果:

库存为零,等待生产:0
库存为零,等待生产:0
库存为零,等待生产:0
生产者生产了一个面包:1
生产者生产了一个面包:2
生产者生产了一个面包:3
生产者生产了一个面包:4
生产者生产了一个面包:5
生产者生产了一个面包:6
生产者生产了一个面包:7
生产者生产了一个面包:8
生产者生产了一个面包:9
生产者生产了一个面包:10
库存满了,等待消费10
库存满了,等待消费10
库存满了,等待消费10
消费者消费了一个面包:9
消费者消费了一个面包:8

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值