Skip to content

最佳实践

并发编程的最佳实践和常见问题解决方案。

1. 避免死锁

1.1 死锁条件

  • 互斥条件
  • 占有并等待
  • 不可抢占
  • 循环等待

1.2 常见场景

java
// ❌ 错误:锁顺序不一致
public void method1() {
    synchronized (lockA) {
        synchronized (lockB) { }
    }
}

public void method2() {
    synchronized (lockB) {
        synchronized (lockA) { }  // 可能死锁
    }
}

// ✅ 正确:统一锁顺序
public void method1() {
    synchronized (lockA) {
        synchronized (lockB) { }
    }
}

public void method2() {
    synchronized (lockA) {  // 保持一致
        synchronized (lockB) { }
    }
}

1.3 解决方案

  • 统一加锁顺序
  • 使用 tryLock 超时
  • 避免嵌套锁

2. 线程池配置

2.1 参数计算

java
int cpuCores = Runtime.getRuntime().availableProcessors();

// CPU密集型
int cpuIntensive = cpuCores + 1;

// IO密集型
int ioIntensive = cpuCores * 2;

2.2 推荐配置

场景核心线程最大线程队列
CPU 密集N+1N+1小队列
IO 密集2N4N较大队列

3. 避免共享可变状态

3.1 使用 ThreadLocal

java
// ❌ 错误:共享可变状态
private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

// ✅ 正确:使用 ThreadLocal
private static final ThreadLocal<SimpleDateFormat> sdf = 
    ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));

public String format(Date date) {
    return sdf.get().format(date);
}

3.2 使用不可变对象

java
// 使用不可变类
public final class ImmutableUser {
    private final String name;
    private final int age;
    
    public ImmutableUser(String name, int age) {
        this.name = name;
        this.age = age;
    }
    // 只有 getter,没有 setter
}

4. 正确使用 volatile

java
// ✅ 适合:状态标志
private volatile boolean running = true;

// ❌ 不适合:复合操作
private volatile int count;
count++;  // 非原子操作!应使用 AtomicInteger

5. 场景速查表

场景推荐方案
简单同步synchronized
需要更多控制ReentrantLock
读多写少ReentrantReadWriteLock
计数器AtomicInteger
高并发计数LongAdder
异步编程CompletableFuture
生产者消费者BlockingQueue
线程复用ThreadPoolExecutor
等待多线程完成CountDownLatch
限流Semaphore