这两个类都属于并发编程里面的内容,如果你没有学习过,肯定不清楚里面是什么一个情况。
CountDownLatch:容许一个或者多个线程等待一个事件集的发生
Cyclicbarrier:可以用于多线程计算数据,最后合并计算结果的应用场景
上面的解释感觉还是很模糊,上代码:
public class CountDownTest { public static void main(String[] args) throws InterruptedException { ThreadFactory buildName = new ThreadFactoryBuilder().setNameFormat("Thread-%d").build(); ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(8, 16, 1000, TimeUnit.SECONDS, new LinkedBlockingQueue<>(20), buildName, new ThreadPoolExecutor.AbortPolicy()); ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap(16); map.put("one", 1); AtomicInteger a = new AtomicInteger(map.get("one")); //这里指定是两个任务,下面用的线程池启动的两个线程,刚好拿完,AtomicInteger 这个类是个原子操作。 CountDownLatch count = new CountDownLatch(2); poolExecutor.execute(() -> { for (int i = 0; i < 10000; i++) { a.getAndIncrement(); } //这里程序完成后,计数器减一 count.countDown(); }); poolExecutor.execute(() -> { for (int i = 0; i < 10000; i++) { a.getAndIncrement(); } //这里程序完成后,计数器减一 count.countDown(); }); //这里等待计数器为零,主线程才会继续执行 count.await(); map.put("one",a.get()); //最终拿到a的结果,是两个线程执行完的结果,数据才能是正确的 System.out.println(a); poolExecutor.shutdown(); } } //综上,主线程会等待两个子线程(集)执行完之后,才会获取a的值(容许一个或者多个线程等待一个事件集的发生)。是不是有感觉了啊!
CyclicBarrier 下面也是举了一个列子,旅游为例,只有等一个团的成员,都到齐了,才能成团出发,更为方便的是,线程(成员)可以重复的成团,我们给定的是三个成团,但是六个线程会分两次。所以该类多用在分批计算,只有等一批数值都计算出结果,才能在其基础上进行下一步操作。
public class CyclicbarrierTest { private static CyclicBarrier cyclicBarrier = new CyclicBarrier(3, new Runnable() { @Override public void run() { System.out.println("成团,出发"); } }); public static void main(String[] args) throws InterruptedException { CyclicbarrierTest test = new CyclicbarrierTest(); test.method(); test.method(); } private static AtomicInteger atomicInteger = new AtomicInteger(1); public void method() throws InterruptedException { ThreadFactory buildName = new ThreadFactoryBuilder().setNameFormat("Thread-%d").build(); ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(8, 16, 1000, TimeUnit.SECONDS, new LinkedBlockingQueue<>(20), buildName, new ThreadPoolExecutor.AbortPolicy()); poolExecutor.execute(() -> { System.out.println("1号来了"); try { cyclicBarrier.await(); System.out.println("开始旅游啦"); } catch (InterruptedException e) { throw new RuntimeException(e); } catch (BrokenBarrierException e) { throw new RuntimeException(e); } }); poolExecutor.execute(() -> { System.out.println("2号来了"); try { cyclicBarrier.await(); System.out.println("开始旅游啦"); } catch (InterruptedException e) { throw new RuntimeException(e); } catch (BrokenBarrierException e) { throw new RuntimeException(e); } }); poolExecutor.execute(() -> { System.out.println("3号来了"); try { cyclicBarrier.await(); System.out.println("开始旅游啦"); } catch (InterruptedException e) { throw new RuntimeException(e); } catch (BrokenBarrierException e) { throw new RuntimeException(e); } }); // System.out.println("cyclicBarrier.getParties() = " + cyclicBarrier.getParties()); // Thread.sleep(1000); // cyclicBarrier.reset(); poolExecutor.execute(() -> { System.out.println("4号来了"); try { atomicInteger.incrementAndGet(); System.out.println("atomicInteger.get() = " + atomicInteger.get()); cyclicBarrier.await(); System.out.println("开始旅游啦"); } catch (InterruptedException e) { throw new RuntimeException(e); } catch (BrokenBarrierException e) { throw new RuntimeException(e); } }); poolExecutor.execute(() -> { System.out.println("5号来了"); try { cyclicBarrier.await(); System.out.println("开始旅游啦"); } catch (InterruptedException e) { throw new RuntimeException(e); } catch (BrokenBarrierException e) { throw new RuntimeException(e); } }); poolExecutor.execute(() -> { System.out.println("6号来了"); try { cyclicBarrier.await(); System.out.println("开始旅游啦"); } catch (InterruptedException e) { throw new RuntimeException(e); } catch (BrokenBarrierException e) { throw new RuntimeException(e); } }); poolExecutor.shutdown(); } }