Java 并发编程核心详解

Java 并发编程核心详解

在 Java 并发编程的世界中,线程安全、锁机制和线程池是构建高性能并发应用的三大基石。本文将深入解析这些核心概念,帮助开发者理解并发编程的本质。

一、线程创建与执行

Java 提供两种主要方式创建线程:实现 Runnable 接口和实现 Callable 接口。


// 实现 Runnable 接口
Runnable task = () -> {
    System.out.println("线程运行:" + Thread.currentThread().getName());
};
new Thread(task).start();

// 实现 Callable 接口(可返回结果)
Callable<String> callable = () -> {
    return "任务执行完成";
};
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(callable);
String result = future.get();

二、线程锁机制

同步是保证线程安全的关键。Java 提供了多种锁机制。

1. synchronized 关键字


public class Counter {
    private int count = 0;
    
    public synchronized void increment() {
        count++;
    }
    
    public synchronized int getCount() {
        return count;
    }
}

2. ReentrantLock(更灵活的锁)


ReentrantLock lock = new ReentrantLock();
lock.lock();
try {
    // 临界区代码
} finally {
    lock.unlock(); // 确保释放锁
}

3. volatile 关键字

volatile 保证变量的可见性,但不保证原子性。


private volatile boolean running = true;

public void stop() {
    running = false;
}

public void run() {
    while (running) {
        // 循环任务
    }
}

三、线程池的使用

线程池可以复用线程,避免频繁创建销毁线程的开销。


// 使用 Executors 工厂
ExecutorService executor = Executors.newFixedThreadPool(4);

// 使用 ThreadPoolExecutor(推荐)
ThreadPoolExecutor executor = new ThreadPoolExecutor(
    4,              // 核心线程数
    8,              // 最大线程数
    60, TimeUnit.SECONDS,
    new LinkedBlockingQueue<>(100), // 任务队列
    new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略
);

四、并发容器

Java 提供了一系列线程安全的集合类。


// ConcurrentHashMap - 线程安全的哈希表
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
map.put("key", 1);

// CopyOnWriteArrayList - 适用于读多写少的场景
CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
list.add("item");

五、原子类

原子类使用 CAS(Compare-And-Swap)机制保证原子操作。


AtomicInteger atomicCount = new AtomicInteger(0);
atomicCount.incrementAndGet();
int value = atomicCount.getAndAdd(10);

六、常见坑点与最佳实践

1. 死锁问题


// 错误示例:嵌套锁可能导致死锁
synchronized(lock1) {
    synchronized(lock2) {
        // ...
    }
}

// 正确做法:统一锁的获取顺序

2. 线程池未关闭


// 错误示例
ExecutorService executor = Executors.newFixedThreadPool(10);
executor.submit(() -> {});

// 正确做法:及时关闭
executor.shutdown();

3. 最佳实践清单

  • 优先使用线程池,避免频繁创建销毁线程
  • 合理设置队列大小,避免 OOM
  • 使用 try-finally 确保锁释放
  • 最小化临界区,减少锁竞争
  • 监控锁竞争情况

七、总结

Java 并发编程 powerful 但也复杂。掌握线程池、锁机制和并发容器的使用,避开常见坑点,才能让应用在高并发场景下依然稳定高效。理解底层原理,选择合适方案,是成为高效 Java 开发者的必经之路。

Java 并发编程技术教程

#Java #并发编程 #多线程 #锁机制 #JUC #技术教程

标签

发表评论