前言
当我们在多线程环境下需要共享一个计数器时,确保计数操作的线程安全性是至关重要的。线程安全的计数器能够确保在多个线程同时访问和修改计数器时,不会出现数据不一致或者竞态条件的问题。常见的实现方式包括使用锁机制(如 synchronized 或 ReentrantLock )、使用原子变量(如 AtomicInteger )。
着两种方式实现的原理都很简单,代码也比较简单。
AtomicInteger实现
AtomicInteger实现原理主要就是通过其原子类的特性,它本身就提供了原子操作。
实现及其使用如下:
public class AtomicCounter implements Runnable{
private static AtomicInteger count = new AtomicInteger(0);
public synchronized static void calc() {
if ((count.get()) < 1000) {
int cur = count.incrementAndGet();// 自增1,返回更新值
System.out.println("线程" + Thread.currentThread().getName() + " 正在运行,当前计数:" + cur);
}
}
public void run() {
while(true)
{
AtomicCounter.calc();
try {
Thread.sleep(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
for (int i = 0; i < 6; i++) {
AtomicCounter thread = new AtomicCounter();
Thread t = new Thread(thread);
t.start();
}
}
}
synchronized实现
synchronized的实现原理主要就是通过锁住变量递增的方法。
代码及其使用如下:
public class SynCounter {
private int count = 0;
public synchronized void increment() {
count++;
System.out.println("线程" + Thread.currentThread().getName() + " 正在运行,当前计数:" + count);
}
public static void main(String[] args) {
SynCounter counter = new SynCounter();
for (int i = 0; i < 5; i++) {
Thread incrementThread = new Thread(() -> {
for (int j = 0; j < 100; j++) {
counter.increment();
try {
Thread.sleep(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
incrementThread.start();
}
}
}