Condition接口简介
发布日期:2021-05-08 23:11:41 浏览次数:18 分类:博客文章

本文共 3509 字,大约阅读时间需要 11 分钟。

本博客系列是学习并发编程过程中的记录总结。由于文章比较多,写的时间也比较散,所以我整理了个目录贴(传送门),方便查阅。

接口简介

Condition可以看做是Obejct类的wait()notify()notifyAll()方法的替代品,与Lock配合使用。

当线程执行condition对象的await方法时,当前线程会立即释放锁,并进入对象的等待区,等待其它线程唤醒或中断。

JUC在实现Conditon对象时,其实是通过实现AQS框架,来实现了一个Condition等待队列,这个在后面讲AQS框架时会详细介绍,目前只要了解Condition如何使用即可。

接口定义

public interface Condition {    void await() throws InterruptedException;    long awaitNanos(long nanosTimeout) throws InterruptedException;        boolean await(long time, TimeUnit unit) throws InterruptedException;    boolean awaitUntil(Date deadline) throws InterruptedException;    void signal();    void signalAll();}

使用示例

wait-notify模式的一个典型应用就是可以实现生产者-消费者模式。让我印象很深是我毕业那年阿里巴巴校园招聘的一个笔试题:

有一个苹果箱,有10个人向这个箱子中每次随机放入一个苹果,有10个人每次随机从这个箱子中随机拿走一个苹果,同时需要满足箱子中的苹果总数不能超过50个。请用代码实现上面的场景(不能使用并发集合框架)

这个题目使用wait-notify模式可以很好地解决。下面使用Condition模式来写下。

public class AppleBoxConditon {    private int appleCount;    private static Lock lock = new ReentrantLock();    private static Condition fullCondition = lock.newCondition();    private static Condition emptyCondition = lock.newCondition();    public void putApple() {        lock.lock();        try {            while (appleCount >= 10) {                try {                    fullCondition.await();                } catch (InterruptedException e) {                    e.printStackTrace();                }            }            appleCount++;            System.out.println("放入一个,当前盒子中苹果数:" + appleCount);            emptyCondition.signalAll();        } finally {            lock.unlock();        }    }    public void takeApple() {        lock.lock();        try{            while (appleCount <= 0) {                try {                    emptyCondition.await();                } catch (InterruptedException e) {                    e.printStackTrace();                }            }            appleCount--;            System.out.println("拿走一个,当前盒子中苹果数:" + appleCount);            fullCondition.signalAll();        }finally {            lock.unlock();        }    }    private static class AppleTaker implements Runnable {        private AppleBoxConditon appleBox;        public AppleTaker(AppleBoxConditon appleBox) {            this.appleBox = appleBox;        }        @Override        public void run() {            while (true) {                appleBox.takeApple();                try {                    TimeUnit.MILLISECONDS.sleep(100);                } catch (InterruptedException e) {                    e.printStackTrace();                }            }        }    }    private static class ApplePutter implements Runnable {        private AppleBoxConditon appleBox;        public ApplePutter(AppleBoxConditon appleBox) {            this.appleBox = appleBox;        }        @Override        public void run() {            while (true) {                appleBox.putApple();                try {                    TimeUnit.MILLISECONDS.sleep(100);                } catch (InterruptedException e) {                    e.printStackTrace();                }            }        }    }    public static void main(String[] args) {        AppleBoxConditon appleBox = new AppleBoxConditon();        for (int i = 0; i < 20; i++) {            Thread t = new Thread(new AppleBoxConditon.ApplePutter(appleBox));            t.setName("ApplePutter:"+i);            t.start();        }        for (int i = 0; i < 20; i++) {            Thread t = new Thread(new AppleBoxConditon.AppleTaker(appleBox));            t.setName("AppleTaker:"+i);            t.start();        }    }}
上一篇:Java 网络编程相关知识
下一篇:同步锁 —— ReentrantReadWriteLock

发表评论

最新留言

哈哈,博客排版真的漂亮呢~
[***.90.31.176]2025年04月05日 08时09分49秒