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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章