Java并发计数器案例如何开发

wen java案例 27

本文目录导读:

Java并发计数器案例如何开发

  1. 最基本的非线程安全计数器
  2. 使用synchronized的线程安全计数器
  3. 使用ReentrantLock的计数器
  4. 使用AtomicInteger的计数器(推荐)
  5. 完整的测试案例
  6. 批量操作的计数器
  7. 性能测试对比
  8. 最佳实践建议

我来为你详细介绍Java并发计数器的开发案例,从简单到复杂逐步实现。

最基本的非线程安全计数器

public class UnsafeCounter {
    private int count = 0;
    public void increment() {
        count++;
    }
    public int getCount() {
        return count;
    }
}

问题:多个线程同时调用increment()时,count++不是原子操作,会导致数据不一致。

使用synchronized的线程安全计数器

public class SynchronizedCounter {
    private int count = 0;
    public synchronized void increment() {
        count++;
    }
    public synchronized int getCount() {
        return count;
    }
}

使用ReentrantLock的计数器

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class LockCounter {
    private int count = 0;
    private final Lock lock = new ReentrantLock();
    public void increment() {
        lock.lock();
        try {
            count++;
        } finally {
            lock.unlock();
        }
    }
    public int getCount() {
        lock.lock();
        try {
            return count;
        } finally {
            lock.unlock();
        }
    }
}

使用AtomicInteger的计数器(推荐)

import java.util.concurrent.atomic.AtomicInteger;
public class AtomicCounter {
    private final AtomicInteger count = new AtomicInteger(0);
    public void increment() {
        count.incrementAndGet();  // 原子自增
    }
    public int getCount() {
        return count.get();
    }
}

完整的测试案例

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class CounterDemo {
    // 1. 高性能计数器 - 使用AtomicInteger
    static class HighPerformanceCounter {
        private AtomicInteger count = new AtomicInteger(0);
        public void increment() {
            count.incrementAndGet();
        }
        public int getCount() {
            return count.get();
        }
    }
    // 2. 支持重置的计数器
    static class ResettableCounter {
        private final AtomicInteger count = new AtomicInteger(0);
        public void increment() {
            count.incrementAndGet();
        }
        public int getCount() {
            return count.get();
        }
        public void reset() {
            count.set(0);
        }
    }
    // 3. 有界计数器(不能超过最大值)
    static class BoundedCounter {
        private final AtomicInteger count = new AtomicInteger(0);
        private final int max;
        public BoundedCounter(int max) {
            this.max = max;
        }
        public boolean increment() {
            while (true) {
                int current = count.get();
                if (current >= max) {
                    return false; // 已达到最大值
                }
                if (count.compareAndSet(current, current + 1)) {
                    return true;
                }
            }
        }
        public int getCount() {
            return count.get();
        }
    }
    // 测试方法
    public static void main(String[] args) throws InterruptedException {
        testAtomicCounter();
        testBoundedCounter();
    }
    private static void testAtomicCounter() throws InterruptedException {
        System.out.println("=== 测试AtomicInteger计数器 ===");
        HighPerformanceCounter counter = new HighPerformanceCounter();
        int threadCount = 100;
        int incrementsPerThread = 1000;
        ExecutorService executor = Executors.newFixedThreadPool(10);
        // 创建100个线程,每个线程自增1000次
        for (int i = 0; i < threadCount; i++) {
            executor.submit(() -> {
                for (int j = 0; j < incrementsPerThread; j++) {
                    counter.increment();
                }
            });
        }
        executor.shutdown();
        executor.awaitTermination(10, TimeUnit.SECONDS);
        int expected = threadCount * incrementsPerThread;
        int actual = counter.getCount();
        System.out.println("期望值: " + expected);
        System.out.println("实际值: " + actual);
        System.out.println("结果正确: " + (expected == actual));
    }
    private static void testBoundedCounter() throws InterruptedException {
        System.out.println("\n=== 测试有界计数器 ===");
        BoundedCounter counter = new BoundedCounter(50);
        ExecutorService executor = Executors.newFixedThreadPool(5);
        // 多个线程尝试增加计数
        for (int i = 0; i < 10; i++) {
            executor.submit(() -> {
                for (int j = 0; j < 20; j++) {
                    boolean success = counter.increment();
                    if (success) {
                        System.out.println(Thread.currentThread().getName() + " 增加成功,当前值: " + counter.getCount());
                    }
                }
            });
        }
        executor.shutdown();
        executor.awaitTermination(5, TimeUnit.SECONDS);
        System.out.println("最终计数值: " + counter.getCount() + " (不应超过50)");
    }
}

批量操作的计数器

import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.IntUnaryOperator;
public class BatchOperationCounter {
    private final AtomicInteger count = new AtomicInteger(0);
    // 批量增加
    public int addAndGet(int delta) {
        return count.addAndGet(delta);
    }
    // 条件更新
    public int updateIf(IntUnaryOperator updateFunction) {
        return count.updateAndGet(updateFunction);
    }
    // 仅在满足条件时更新
    public boolean incrementIf(boolean condition) {
        while (true) {
            int current = count.get();
            if (!condition) {
                return false;
            }
            if (count.compareAndSet(current, current + 1)) {
                return true;
            }
        }
    }
    public int getCount() {
        return count.get();
    }
}

性能测试对比

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
public class CounterPerformanceTest {
    public static void main(String[] args) throws InterruptedException {
        int threadCount = 10;
        int iterations = 1000000;
        // 测试synchronized
        long syncTime = testSyncCounter(threadCount, iterations);
        System.out.println("synchronized耗时: " + syncTime + "ms");
        // 测试AtomicInteger
        long atomicTime = testAtomicCounter(threadCount, iterations);
        System.out.println("AtomicInteger耗时: " + atomicTime + "ms");
    }
    private static long testSyncCounter(int threadCount, int iterations) throws InterruptedException {
        SynchronizedCounter counter = new SynchronizedCounter();
        CountDownLatch latch = new CountDownLatch(threadCount);
        long start = System.currentTimeMillis();
        for (int i = 0; i < threadCount; i++) {
            new Thread(() -> {
                for (int j = 0; j < iterations; j++) {
                    counter.increment();
                }
                latch.countDown();
            }).start();
        }
        latch.await();
        return System.currentTimeMillis() - start;
    }
    private static long testAtomicCounter(int threadCount, int iterations) throws InterruptedException {
        AtomicInteger counter = new AtomicInteger(0);
        CountDownLatch latch = new CountDownLatch(threadCount);
        long start = System.currentTimeMillis();
        for (int i = 0; i < threadCount; i++) {
            new Thread(() -> {
                for (int j = 0; j < iterations; j++) {
                    counter.incrementAndGet();
                }
                latch.countDown();
            }).start();
        }
        latch.await();
        return System.currentTimeMillis() - start;
    }
}

最佳实践建议

  1. 优先使用AtomicInteger:性能最好,实现简单
  2. 考虑使用LongAdder:高并发统计场景,性能更优
  3. 注意CAS的ABA问题:AtomicStampedReference可以解决
  4. 合理选择锁粒度:根据实际需求选择悲观锁或乐观锁
// 高并发统计场景使用LongAdder
import java.util.concurrent.atomic.LongAdder;
public class LongAdderCounter {
    private final LongAdder count = new LongAdder();
    public void increment() {
        count.increment();
    }
    public long getCount() {
        return count.sum(); // 注意:sum后会重置,需要重新累加
    }
}

这些示例涵盖了常见的并发计数器实现方案,你可以根据具体需求选择最适合的实现方式。

抱歉,评论功能暂时关闭!