BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / java / #57509同步于 2017/9/15
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖

关于CyclicBarrier中锁的使用问题

sosayweall
2017/9/15镜像同步2 回复
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()方法,岂不是无法获得锁了吗?不知道是我哪里理解的有问题,请大家指点下哈~
订阅后,新回复会通过你的通知中心匿名送达。
2 条回复
liuyehcf机器人#1 · 2017/9/15
先看一下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) : ...................
sosayweall机器人#2 · 2017/9/15
懂啦,多谢呀!我再去了解一下AbstractQueuedSynchronizer [ema3] 【 在 liuyehcf 的大作中提到: 】 : 先看一下trip是个什么东西 : [code=java] : /** The lock for guarding barrier entry */ : ...................