java如何防止并发
防止Java并发问题的常见方法
使用synchronized关键字
通过synchronized修饰方法或代码块,确保同一时间只有一个线程能访问共享资源。
示例:
public synchronized void increment() {
counter++;
}
使用ReentrantLockjava.util.concurrent.locks.ReentrantLock提供更灵活的锁控制,支持公平锁和尝试锁。
示例:
private final ReentrantLock lock = new ReentrantLock();
public void updateResource() {
lock.lock();
try {
// 临界区代码
} finally {
lock.unlock();
}
}
使用原子类java.util.concurrent.atomic包下的类(如AtomicInteger)通过CAS(Compare-And-Swap)实现无锁线程安全。
示例:
private AtomicInteger counter = new AtomicInteger(0);
public void increment() {
counter.incrementAndGet();
}
使用并发集合
替换HashMap为ConcurrentHashMap,ArrayList为CopyOnWriteArrayList等线程安全集合。
示例:

ConcurrentHashMap<String, String> map = new ConcurrentHashMap<>();
使用volatile关键字
确保变量的修改对其他线程立即可见,适用于单写多读场景。
示例:
private volatile boolean flag = false;
使用线程局部变量ThreadLocal为每个线程维护独立的变量副本,避免共享。
示例:

private ThreadLocal<SimpleDateFormat> dateFormat =
ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));
使用不可变对象
设计不可变类(如String),避免状态修改导致的并发问题。
示例:
public final class ImmutableValue {
private final int value;
public ImmutableValue(int value) { this.value = value; }
public int getValue() { return value; }
}
使用CountDownLatch/CyclicBarrier
协调多线程的执行顺序,适用于分阶段任务。
示例:
CountDownLatch latch = new CountDownLatch(3);
// 线程中调用 latch.countDown();
latch.await(); // 等待所有线程完成
选择依据
- 低竞争场景:优先考虑原子类或
volatile。 - 高竞争场景:使用锁(
synchronized或ReentrantLock)。 - 数据共享需求:根据读写比例选择并发集合。






