本文共 2967 字,大约阅读时间需要 9 分钟。
CyclicBarrier(回环栅栏)通过以下字段实现线程安全:
CyclicBarrier 提供两个重载构造函数:
public CyclicBarrier(int parties) { this(parties, null);}public CyclicBarrier(int parties, Runnable barrierAction) { if (parties <= 0) throw new IllegalArgumentException(); this.parties = parties; this.count = parties; this.barrierCommand = barrierAction;} dowait(false, 0L)。dowait(true, unit.toNanos(timeout))。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) { boolean ranAction = false; try { final Runnable command = barrierCommand; if (command != null) command.run(); ranAction = true; nextGeneration(); return 0; } finally { if (!ranAction) breakBarrier(); } } 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 { 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(); }} private void breakBarrier() { generation.broken = true; count = parties; trip.signalAll();} private void nextGeneration() { trip.signalAll(); count = parties; generation = new Generation();} public void reset() { final ReentrantLock lock = this.lock; lock.lock(); try { breakBarrier(); nextGeneration(); } finally { lock.unlock(); }} 在dowait方法中,锁是在finally块中释放的。第一个线程获取锁后进入等待状态,其他线程如何获取锁?答案在于Condition的await方法内部,通过unparkSuccessor唤醒后继线程,允许它们获取锁继续执行。
转载地址:http://slkkz.baihongyu.com/