# Java并发问题

# 问题一:线程安全问题

# 问题描述

  • 多个线程同时访问共享资源导致数据不一致
  • 操作的原子性无法保证
  • 计数器累加出现错误
  • 延迟初始化导致重复创建对象

# 解决方案

  1. 使用synchronized关键字
public class Counter {
    private int count = 0;
    
    public synchronized void increment() {
        count++;
    }
    
    public synchronized int getCount() {
        return count;
    }
}
  1. 使用并发工具类
// 使用AtomicInteger保证原子性
public class AtomicCounter {
    private AtomicInteger count = new AtomicInteger(0);
    
    public void increment() {
        count.incrementAndGet();
    }
    
    public int getCount() {
        return count.get();
    }
}

// 使用线程安全的集合类
Map<String, Object> map = new ConcurrentHashMap<>();
List<String> list = new CopyOnWriteArrayList<>();
  1. 最佳实践
  • 优先使用并发集合而非同步集合
  • 选择合适的锁粒度
  • 使用读写锁分离读写操作
  • 考虑使用乐观锁

# 问题二:死锁问题

# 问题描述

  • 多个线程互相等待对方持有的锁
  • 资源分配顺序不当
  • 嵌套锁导致的死锁
  • 分布式系统中的死锁

# 解决方案

  1. 使用ReentrantLock避免死锁
public class SafeOperation {
    private final ReentrantLock lock1 = new ReentrantLock();
    private final ReentrantLock lock2 = new ReentrantLock();
    
    public void operation() {
        boolean firstLock = false;
        boolean secondLock = false;
        try {
            firstLock = lock1.tryLock(1, TimeUnit.SECONDS);
            if (firstLock) {
                secondLock = lock2.tryLock(1, TimeUnit.SECONDS);
            }
            if (firstLock && secondLock) {
                // 执行操作
            }
        } catch (InterruptedException e) {
            // 处理异常
        } finally {
            if (secondLock) lock2.unlock();
            if (firstLock) lock1.unlock();
        }
    }
}
  1. 最佳实践
  • 按固定顺序获取锁
  • 使用tryLock尝试获取锁
  • 设置锁超时时间
  • 避免在锁内调用外部方法

# 问题三:线程池使用不当

# 问题描述

  • 线程池配置不合理
  • 任务队列过载
  • 线程泄漏
  • 任务执行超时

# 解决方案

  1. 合理配置线程池
ThreadPoolExecutor executor = new ThreadPoolExecutor(
    5,                      // 核心线程数
    10,                     // 最大线程数
    60L, TimeUnit.SECONDS,  // 线程空闲超时时间
    new ArrayBlockingQueue<>(100),  // 任务队列
    new ThreadPoolExecutor.CallerRunsPolicy()  // 拒绝策略
);
  1. 最佳实践
  • 根据任务特点选择线程池类型
  • 设置合理的任务队列大小
  • 实现优先级任务调度
  • 定期监控线程池状态