返回信息流CyclicBarrier源码中await方法的实现是调用私有的dowait()方法。对其中锁的使用有一点困惑。源码如下:
private int dowait(boolean timed, long nanos)
throws InterruptedException, BrokenBarrierException,
TimeoutException {
final ReentrantLock lock = this.lock;
lock.lock();
try {
final Generation g = generation;
if (g.broken)
throw new BrokenBarrierException();
if (Thread.interrupted()) {
breakBarrier();
throw new InterruptedException();
}
int index = --count;
if (index == 0) { // tripped
boolean ranAction = false;
try {
final Runnable command = barrierCommand;
if (command != null)
command.run();
ranAction = true;
nextGeneration();
return 0;
} finally {
if (!ranAction)
breakBarrier();
}
}
// loop until tripped, broken, interrupted, or timed out
for (;;) {
try {
if (!timed)
trip.await();
else if (nanos > 0L)
nanos = trip.awaitNanos(nanos);
} catch (InterruptedException ie) {
if (g == generation && ! g.broken) {
breakBarrier();
throw ie;
} else {
// We're about to finish waiting even if we had not
// been interrupted, so this interrupt is deemed to
// "belong" to subsequent execution.
Thread.currentThread().interrupt();
}
}
if (g.broken)
throw new BrokenBarrierException();
if (g != generation)
return index;
if (timed && nanos <= 0L) {
breakBarrier();
throw new TimeoutException();
}
}
} finally {
lock.unlock();
}
}
方法中使用了ReentrantLock来保证操作的原子性,假定一个线程调用barrier.await()方法获得了锁,将阻塞在trip.await();这里,那此时如果再有一个线程调用barrier.await()方法,岂不是无法获得锁了吗?不知道是我哪里理解的有问题,请大家指点下哈~
这是一条镜像帖。来源:北邮人论坛 / java / #57509同步于 2017/9/15
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖
关于CyclicBarrier中锁的使用问题
sosayweall
2017/9/15镜像同步2 回复
订阅后,新回复会通过你的通知中心匿名送达。
2 条回复
先看一下trip是个什么东西
/** The lock for guarding barrier entry */
private final ReentrantLock lock = new ReentrantLock();
/** Condition to wait on until tripped */
private final Condition trip = lock.newCondition();
这个trip是由ReentrantLock产生的一个条件对象,其具体的类型是ConditionObject。ConditionObject是AbstractQueuedSynchronizer的一个内部类,ReentrantLock仅仅是对AbstractQueuedSynchronizer进行了一层封装,并提供加锁解锁的具体语意。ConditionObject.await方法调用必须处于锁定状态,也就是你给出源码的lock.lcok()与lock.unlock()之间,并且该方法会释放占有的独占锁,并且将当前线程封装成Node放入ConditionObject的等待队列中。这个机制类似于wait/notify(wait和notify必须要在synchronized块之内才能调用,不然可能会抛出异常,且wait会释放持有的锁)
如果对并发包源码感兴趣,建议先看AbstractQueuedSynchronizer(AQS)这个类,这个是实现锁机制的基础也是核心。
【 在 sosayweall 的大作中提到: 】
: CyclicBarrier源码中await方法的实现是调用私有的dowait()方法。对其中锁的使用有一点困惑。源码如下:
: [code=java]
: private int dowait(boolean timed, long nanos)
: ...................
懂啦,多谢呀!我再去了解一下AbstractQueuedSynchronizer
[ema3]
【 在 liuyehcf 的大作中提到: 】
: 先看一下trip是个什么东西
: [code=java]
: /** The lock for guarding barrier entry */
: ...................