您现在的位置是:首页 > Java 当前栏目 Java并发 - 计数器 JAVA 并发 线程 执行 2023-03-02 11:10:41 时间 ## CountDownLatch ## 可理解为减法计数器 public void testCountDownLatch() throws InterruptedException { // 减法计数器初始值 CountDownLatch countDownLatch = new CountDownLatch(6); for (int i = 0; i < 6; i++) { new Thread(() -> { System.out.println(Thread.currentThread().getName() + "---> 执行完毕"); // 数量减1 countDownLatch.countDown(); },"线程"+i).start(); } // 等待计数器归零,再继续向下执行 countDownLatch.await(); System.out.println("所有线程执行完毕"); } ## CyclicBarrier ## 可理解为加法计数器 public void testCyclicBarrier() { CyclicBarrier cyclicBarrier = new CyclicBarrier(6, () -> { System.out.println("所有线程执行完毕"); }); for (int i = 0; i < 6; i++) { final int temp = i; new Thread(() -> { System.out.println(Thread.currentThread().getName() + "---->" + temp); try { cyclicBarrier.await(); } catch (InterruptedException | BrokenBarrierException e) { e.printStackTrace(); } }).start(); } } JDK8新增了以下更新器和计数器的API: 更新器:DoubleAccumulator、LongAccumulator 计数器:DoubleAdder、LongAdder 计数器增强版,高并发下性能更好。经过以下三中方式对比,发现LongAdder性能是最好的。 public class LongAdderDemo { private long count = 0; public void testSync() throws InterruptedException { for (int i = 0; i < 3; i++) { new Thread(() -> { long starttime = System.currentTimeMillis(); while (System.currentTimeMillis() - starttime < 2000) { synchronized (this) { ++count; } } long endtime = System.currentTimeMillis(); System.out.println("SyncThread spend:" + (endtime - starttime) + "ms,count=" + count); }).start(); } } private AtomicLong count2 = new AtomicLong(0L); public void testAtomic() { for (int i = 0; i < 3; i++) { new Thread(() -> { long starttime = System.currentTimeMillis(); while (System.currentTimeMillis() - starttime < 2000) { count2.incrementAndGet(); } long endTime = System.currentTimeMillis(); System.out.println("AtomicThread spend:" + (endTime - starttime) + "ms,count=" + count2.get()); }).start(); } } private LongAdder count3 = new LongAdder(); public void testLongAdder() { for (int i = 0; i < 3; i++) { new Thread(() -> { long starttime = System.currentTimeMillis(); while (System.currentTimeMillis() - starttime < 2000) { count3.increment(); } long endTime = System.currentTimeMillis(); System.out.println("LongAdderThread spend:" + (endTime - starttime) + "ms,count=" + count3.sum()); }).start(); } } public static void main(String[] args) throws Exception{ LongAdderDemo demo = new LongAdderDemo(); demo.testSync(); demo.testAtomic(); demo.testLongAdder(); } } 运行结果: SyncThread spend:2000ms,count=27297961 SyncThread spend:2000ms,count=27297961 SyncThread spend:2000ms,count=27297961 LongAdderThread spend:2000ms,count=233398030 LongAdderThread spend:2000ms,count=233398030 AtomicThread spend:2000ms,count=96741082 AtomicThread spend:2000ms,count=96741082 LongAdderThread spend:2000ms,count=233398030 AtomicThread spend:2000ms,count=96741082 LongAdder适用于频繁更新但不会频繁读取。汇总统计信息时使用分成多个操作单元,不同线程更新不同的单元,只有需要汇总的时候才计算所有单元的操作。 一般应用于统计次数,例如统计接口的调用次数。 LonAdder 的increment()和sum()方法: public void increment() { add(1L); } public void add(long x) { // 使用多个内存单元,线程分开累加,保证线程安全又能提高效率 Cell[] as; long b, v; int m; Cell a; if ((as = cells) != null || !casBase(b = base, b + x)) { boolean uncontended = true; if (as == null || (m = as.length - 1) < 0 || (a = as[getProbe() & m]) == null || !(uncontended = a.cas(v = a.value, v + x))) longAccumulate(x, null, uncontended); } } public long sum() { Cell[] as = cells; Cell a; long sum = base; if (as != null) { for (int i = 0; i < as.length; ++i) { if ((a = as[i]) != null) sum += a.value; } } return sum; } sum方法中在累加每个单元的运算结果。 LongAdder在JDK8后新增了一个增强类LongAccumulator: public void testLongAdderAccumulator() { LongAccumulator accumulator = new LongAccumulator(new LongBinaryOperator() { @Override public long applyAsLong(long left, long right) { // 返回最大值,自定义返回值 return left > right ? left : right; } }, 0); for (int i = 0; i < 100; i++) { int finalI = i; new Thread(() -> { accumulator.accumulate(finalI); }).start(); } // 获取指定返回的值,如最大值、中间值 、最小值等 System.out.println(accumulator.get()); } 本文地址: Java并发 - 计数器 相关文章 算法-java实现 java8-实战 Java简单计算器 java集合介绍 java 冒泡排序 java冒泡排序 java冒泡排序 java冒泡排序 Java 基础知识 Java 基础知识 Java—打印图形 java List分组 java list分组 基数排序java Java线程 Java线程 Java--线程 static变量 java java final关键字 java-抽象类