
Condition接口简介
发布日期:2021-05-08 23:11:41
浏览次数:18
分类:博客文章
本文共 3509 字,大约阅读时间需要 11 分钟。
本博客系列是学习并发编程过程中的记录总结。由于文章比较多,写的时间也比较散,所以我整理了个目录贴(传送门),方便查阅。
接口简介
Condition可以看做是Obejct类的wait()
、notify()
、notifyAll()
方法的替代品,与Lock配合使用。
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(); } }}
发表评论
最新留言
哈哈,博客排版真的漂亮呢~
[***.90.31.176]2025年04月05日 08时09分49秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
(数据科学学习手札27)sklearn数据集分割方法汇总
2019-03-06
(数据科学学习手札40)tensorflow实现LSTM时间序列预测
2019-03-06
[整理] 哪些集合类是线程安全的?(Java)
2019-03-06
8 个警示和学习的 5 个阶段
2019-03-06
c# 图片带水纹波动
2019-03-06
H5 贪吃蛇源码
2019-03-06
从零开始学安全(十六)● Linux vim命令
2019-03-06
从零开始学安全(三十四)●百度杯 ctf比赛 九月场 sqli
2019-03-06
3389连接痕迹清除
2019-03-06
发生系统错误 6118
2019-03-06
阿里巴巴Json工具-Fastjson教程
2019-03-06
Spring Cloud Gateway - 快速开始
2019-03-06
Spring Security 实战干货:理解AuthenticationManager
2019-03-06
Java对象转JSON时如何动态的增删改查属性
2019-03-06
Python 面向对象进阶
2019-03-06
Linux常用统计命令之wc
2019-03-06
Git安装及使用以及连接GitHub方法详解
2019-03-06
docker容器与虚拟机的区别
2019-03-06
shell脚本里使用echo输出颜色
2019-03-06
Python2跟Python3的区别
2019-03-06