本文目录导读:

- 最基本的非线程安全计数器
- 使用synchronized的线程安全计数器
- 使用ReentrantLock的计数器
- 使用AtomicInteger的计数器(推荐)
- 完整的测试案例
- 批量操作的计数器
- 性能测试对比
- 最佳实践建议
我来为你详细介绍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;
}
}
最佳实践建议
- 优先使用AtomicInteger:性能最好,实现简单
- 考虑使用LongAdder:高并发统计场景,性能更优
- 注意CAS的ABA问题:AtomicStampedReference可以解决
- 合理选择锁粒度:根据实际需求选择悲观锁或乐观锁
// 高并发统计场景使用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后会重置,需要重新累加
}
}
这些示例涵盖了常见的并发计数器实现方案,你可以根据具体需求选择最适合的实现方式。
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播