java如何控制并发
控制并发的常见方法
在Java中控制并发主要通过以下几种机制实现,确保多线程环境下的数据安全和性能优化。
使用synchronized关键字
synchronized是最基础的线程同步机制,可以修饰方法或代码块,确保同一时间只有一个线程访问共享资源。
public class Counter {
private int count = 0;
public synchronized void increment() {
count++;
}
}
使用ReentrantLock
ReentrantLock是java.util.concurrent.locks包中的显式锁,提供比synchronized更灵活的锁控制,支持公平锁和可中断锁。
import java.util.concurrent.locks.ReentrantLock;
public class Counter {
private int count = 0;
private ReentrantLock lock = new ReentrantLock();
public void increment() {
lock.lock();
try {
count++;
} finally {
lock.unlock();
}
}
}
使用volatile关键字
volatile确保变量的可见性,但不保证原子性。适用于一写多读的场景。

public class SharedResource {
private volatile boolean flag = false;
public void toggleFlag() {
flag = !flag;
}
}
使用原子类(AtomicInteger等)
java.util.concurrent.atomic包提供原子类(如AtomicInteger),通过CAS(Compare-And-Swap)实现无锁线程安全操作。
import java.util.concurrent.atomic.AtomicInteger;
public class Counter {
private AtomicInteger count = new AtomicInteger(0);
public void increment() {
count.incrementAndGet();
}
}
使用并发集合
Java提供线程安全的并发集合(如ConcurrentHashMap、CopyOnWriteArrayList),避免显式同步。

import java.util.concurrent.ConcurrentHashMap;
public class Cache {
private ConcurrentHashMap<String, String> map = new ConcurrentHashMap<>();
public void put(String key, String value) {
map.put(key, value);
}
}
使用CountDownLatch和CyclicBarrier
CountDownLatch和CyclicBarrier用于协调多个线程的执行顺序。
import java.util.concurrent.CountDownLatch;
public class TaskRunner {
public static void main(String[] args) throws InterruptedException {
CountDownLatch latch = new CountDownLatch(3);
new Thread(() -> {
// 执行任务
latch.countDown();
}).start();
latch.await(); // 等待所有任务完成
}
}
使用Semaphore
Semaphore控制对共享资源的访问数量,适用于限流场景。
import java.util.concurrent.Semaphore;
public class ResourcePool {
private Semaphore semaphore = new Semaphore(3); // 允许3个线程同时访问
public void accessResource() throws InterruptedException {
semaphore.acquire();
try {
// 访问资源
} finally {
semaphore.release();
}
}
}
使用ThreadLocal
ThreadLocal为每个线程提供独立的变量副本,避免共享变量的问题。
public class UserContext {
private static ThreadLocal<String> user = new ThreadLocal<>();
public static void setUser(String username) {
user.set(username);
}
public static String getUser() {
return user.get();
}
}
选择依据
- 简单同步:优先使用
synchronized或ReentrantLock。 - 高性能无锁:选择原子类或并发集合。
- 线程协作:使用
CountDownLatch、CyclicBarrier或Semaphore。 - 线程隔离:使用
ThreadLocal。






