Java API例子Reentrantlock使用多个条件变量的含义

ddddouche 2016-08-24 09:10:57
查看了下JDK里面的Reentrantlock,使用了两个条件变量去控制缓冲区的编写,JDK源码如下

class BoundedBuffer {
final Lock lock = new ReentrantLock();
final Condition notFull = lock.newCondition();
final Condition notEmpty = lock.newCondition();

final Object[] items = new Object[100];
int putptr, takeptr, count;

public void put(Object x) throws InterruptedException {
lock.lock();
try {
while (count == items.length)
notFull.await();
items[putptr] = x;
if (++putptr == items.length) putptr = 0;
++count;
notEmpty.signal();
} finally {
lock.unlock();
}
}

public Object take() throws InterruptedException {
lock.lock();
try {
while (count == 0)
notEmpty.await();
Object x = items[takeptr];
if (++takeptr == items.length) takeptr = 0;
--count;
notFull.signal();
return x;
} finally {
lock.unlock();
}
}
}

为什么API的例子使用了两个Condition条件去控制代码执行?用一个不可以吗,那么synchronized关键字控制的也是一个条件的唤醒和等待。是否说明了synchronized关键字控制的代码有问题?
...全文
279 2 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
Rookie-D 2020-03-07
  • 打赏
  • 举报
回复
我的理解是: 对于 synchronized 来说,更常用的可能是在:1. 两个线程之间存在某个共享变量的交互,比如消费者和生产者;2. 多个线程都想调用某个线程的一个同步方法时。而 ReentrantLock 可能更多地用于多个线程“有条件”地交互。 比如对于一个“工作”线程 Work,它执行完后,可以选择去执行看书Read、洗澡Shower、打球Basketball 等等线程,而如果我只想去打球然后洗个澡,那我可以选择唤醒Shower线程和Basketball线程,即`Shower.signal();`和`Basketball.signal()`。 如果在这个场景使用 synchronized 的话,那么在Work线程执行完后,它释放了锁,而其它的线程会去争着得到锁,这样到底执行哪个线程就不一定了。
ddddouche 2016-08-26
  • 打赏
  • 举报
回复
ReentrantLock的condition可以按条件唤醒及休眠,比synchronized关键字优秀的是synchronized在使用notify时可能唤醒的不是自己要唤醒的线程。

62,634

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧