案例
public static void main(String[] args) throws Exception{ Map<String,Object> map = new A().test(); for(Map.Entry<String, Object> e : map.entrySet()){ System.out.println(e.getKey()+" : "+e.getValue()); } } public Map<String,Object> test()throws Exception{ final boolean[] flag = {false}; Map<String, Object> map = new HashMap<>(); CyclicBarrier barrier = new CyclicBarrier(3, new Runnable() { @Override public void run() { System.out.println("所有线程都执行完了,合并返回结果"); flag[0] = true; } }); // 异步调用三个类处理业务逻辑 new Thread(()->{ try { Thread.sleep(1000); System.out.println("线程一执行 自己的一部分工作..."); map.put("code",1); barrier.await(); System.out.println("线程一执行完"); }catch (Exception e){ e.printStackTrace(); } }).start(); new Thread(()->{ try { Thread.sleep(1000); System.out.println("线程二执行 自己的一部分工作..."); map.put("data",null); barrier.await(); System.out.println("线程二执行完"); }catch (Exception e){ e.printStackTrace(); } }).start(); new Thread(()->{ try { Thread.sleep(1000); System.out.println("线程三执行 自己的一部分工作..."); map.put("msg", "删除成功"); barrier.await(); System.out.println("线程三执行完"); }catch (Exception e){ e.printStackTrace(); } }).start(); // 等三个任务执行完 while(!flag[0]){ //Thread.sleep(100); } return map; }
源码阅读
创建 public CyclicBarrier(int parties, Runnable barrierAction) { if (parties <= 0) throw new IllegalArgumentException(); // 就是将设置的 parties 和 runnable 存起来 this.parties = parties; this.count = parties; this.barrierCommand = barrierAction; } await() private int dowait(boolean timed, long nanos) throws InterruptedException, BrokenBarrierException, TimeoutException { //1. 首先上来就加上了 ReentrantLock 锁 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(); } // 2. 我们初始化的时候就设置了count,现在递减 int index = --count; if (index == 0) { // tripped // 3. 这是第一种情况,index==0 说明是最后一个线程在执行任务了 boolean ranAction = false; try { // 4. 获取到我们初始化传入的命令,也就是说我们的那个 run() 不是线程来着,就是一个普通方法。 final Runnable command = barrierCommand; if (command != null) // 5. 执行 run() 方法 command.run(); ranAction = true; // 6. 将 count重置成 partities数量,并通过Condition.signalAll(),唤醒在队列里排队的线程,也就是调用 await() 的线程,他们会尝试获取lock锁,因为那些线程此时被唤醒过后,都会进入Lock锁的AQS锁等待队列里去。 nextGeneration(); return 0; } finally { // 7. 唤醒后面节点 if (!ranAction) breakBarrier(); } } // loop until tripped, broken, interrupted, or timed out for (;;) { try { if (!timed) // 3. 这里就是第二中情况了 // Condition.await(),底层,其实是释放了当前的lock锁,触发了把当前线程加入condition等待队列里,挂起当前线程 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(); } }
。