1. 使用AtomicInteger
AtomicInteger 类提供了原子操作,可以在线程安全的情况下进行自增操作。它是 Java 并发包 (java.util.concurrent.atomic) 中的一个类,专门用于原子操作。
import java.util.concurrent.atomic.AtomicInteger;
public class SafeIncrementExample {
private static AtomicInteger counter = new AtomicInteger(0);
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(() -> {
counter.incrementAndGet();
}).start();
}
// 等待所有线程完成
while (Thread.activeCount() > 1) {
Thread.yield();
}
System.out.println("Final count: " + counter.get());
}
}
在这个示例中,我们使用 AtomicInteger 的 incrementAndGet() 方法来实现线程安全的自增操作。
2. 使用 synchronized 关键字
可以使用 synchronized 关键字来同步一个方法或代码块,确保同一时间只有一个线程可以访问。
public class SafeIncrementExample {
private static int counter = 0;
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(() -> {
incrementCounter();
}).start();
}
// 等待所有线程完成
while (Thread.activeCount() > 1) {
Thread.yield();
}
System.out.println("Final count: " + counter);
}
private static synchronized void incrementCounter() {
counter++;
}
}
在这个示例中,我们使用 synchronized 关键字来同步 incrementCounter 方法,确保同一时间只有一个线程可以执行该方法。
3. 使用 ReentrantLock
ReentrantLock 是 Java 并发包中的一个类,提供了一种更灵活的锁机制,可以用来实现线程安全的自增操作。
import java.util.concurrent.locks.ReentrantLock;
public class SafeIncrementExample {
private static int counter = 0;
private static ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(() -> {
incrementCounterWithLock();
}).start();
}
// 等待所有线程完成
while (Thread.activeCount() > 1) {
Thread.yield();
}
System.out.println("Final count: " + counter);
}
private static void incrementCounterWithLock() {
lock.lock();
try {
counter++;
} finally {
lock.unlock();
}
}
}
在这个示例中,我们使用 ReentrantLock 来同步自增操作,确保同一时间只有一个线程可以执行该操作。
4. 使用 ThreadLocal
如果每个线程只需要对自己的计数器进行自增,可以使用 ThreadLocal 来为每个线程提供一个独立的副本。
import java.util.concurrent.ThreadLocalRandom;
public class SafeIncrementExample {
private static ThreadLocal<Integer> threadLocalCounter = new ThreadLocal<>();
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(() -> {
incrementThreadLocalCounter();
}).start();
}
// 等待所有线程完成
while (Thread.activeCount() > 1) {
Thread.yield();
}
int finalCount = threadLocalCounter.get().intValue();
System.out.println("Final count: " + finalCount);
}
private static void incrementThreadLocalCounter() {
int current = threadLocalCounter.get();
if (current == null) {
current = 0;
}
threadLocalCounter.set(current + 1);
}
}
5. 总结
- AtomicInteger:提供原子操作,最适合实现线程安全的自增操作。
- synchronized 关键字:可以同步方法或代码块,确保同一时间只有一个线程可以访问。
- ReentrantLock:提供更灵活的锁机制,可以用来实现线程安全的自增操作。
- ThreadLocal:为每个线程提供独立的计数器副本,适用于不需要共享计数器的情况。