JUC(Java Util Concurrent) 是 Java 标准库中用于支持并发编程的模块,提供了丰富的工具类和框架,帮助开发者编写高效、线程安全的并发程序。JUC 模块自 Java 5 引入,是 Java 并发编程的核心部分。
1. JUC 的核心组件
1.1 原子类(Atomic Classes)
-
作用:提供原子操作,避免使用锁的情况下实现线程安全。
-
常见类:
-
AtomicInteger
:原子操作的整数。 -
AtomicLong
:原子操作的长整数。 -
AtomicReference
:原子操作的对象引用。
-
-
示例:
复制
AtomicInteger atomicInt = new AtomicInteger(0); atomicInt.incrementAndGet(); // 原子自增
1.2 锁机制(Locks)
-
作用:提供比
synchronized
更灵活的锁机制。 -
常见类:
-
ReentrantLock
:可重入锁,支持公平锁和非公平锁。 -
ReentrantReadWriteLock
:读写锁,支持读多写少的场景。 -
StampedLock
:改进的读写锁,支持乐观读。
-
-
示例:
复制
ReentrantLock lock = new ReentrantLock(); lock.lock(); try {// 临界区代码 } finally {lock.unlock(); }
1.3 并发集合(Concurrent Collections)
-
作用:提供线程安全的集合类。
-
常见类:
-
ConcurrentHashMap
:线程安全的哈希表。 -
CopyOnWriteArrayList
:写时复制的线程安全列表。 -
BlockingQueue
:阻塞队列,支持生产者-消费者模式。
-
-
示例:
复制
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>(); map.put("key", 1);
1.4 线程池(Thread Pools)
-
作用:管理线程的生命周期,避免频繁创建和销毁线程。
-
常见类:
-
ExecutorService
:线程池接口。 -
ThreadPoolExecutor
:可配置的线程池实现。 -
Executors
:工厂类,提供常用的线程池配置。
-
-
示例:
复制
ExecutorService executor = Executors.newFixedThreadPool(4); executor.submit(() -> System.out.println("Task running")); executor.shutdown();
1.5 同步工具(Synchronizers)
-
作用:提供线程间的协调机制。
-
常见类:
-
CountDownLatch
:等待一组线程完成。 -
CyclicBarrier
:让一组线程互相等待。 -
Semaphore
:控制同时访问资源的线程数。 -
Phaser
:更灵活的同步屏障。
-
-
示例:
复制
CountDownLatch latch = new CountDownLatch(3); for (int i = 0; i < 3; i++) {new Thread(() -> {System.out.println("Task done");latch.countDown();}).start(); } latch.await(); // 等待所有任务完成
1.6 Future 和 CompletableFuture
-
作用:支持异步编程。
-
常见类:
-
Future
:表示异步计算的结果。 -
CompletableFuture
:支持更复杂的异步编程(如链式调用、异常处理)。
-
-
示例:
复制
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 42); future.thenAccept(result -> System.out.println("Result: " + result));
2. JUC 的优势
2.1 高性能
-
JUC 提供了高效的并发工具(如
ConcurrentHashMap
、AtomicInteger
),避免了锁竞争。
2.2 灵活性
-
JUC 提供了比
synchronized
更灵活的锁机制(如ReentrantLock
、StampedLock
)。
2.3 可扩展性
-
JUC 的线程池和并发集合支持高并发场景。
2.4 丰富的工具
-
JUC 提供了多种同步工具(如
CountDownLatch
、Semaphore
),满足不同的并发需求。
3. JUC 的应用场景
3.1 高并发数据处理
-
使用
ConcurrentHashMap
处理并发数据。 -
使用
BlockingQueue
实现生产者-消费者模式。
3.2 任务调度
-
使用线程池(如
ThreadPoolExecutor
)管理任务执行。
3.3 异步编程
-
使用
CompletableFuture
实现异步任务编排。
3.4 线程同步
-
使用
CountDownLatch
、CyclicBarrier
等工具实现线程间的协调。
4. JUC 的实践示例
4.1 使用线程池执行任务
复制
ExecutorService executor = Executors.newFixedThreadPool(4); for (int i = 0; i < 10; i++) {executor.submit(() -> System.out.println("Task executed by " + Thread.currentThread().getName())); } executor.shutdown();
4.2 使用 ConcurrentHashMap
复制
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>(); map.put("key1", 1); map.put("key2", 2); System.out.println(map.get("key1")); // 输出 1
4.3 使用 CountDownLatch
复制
CountDownLatch latch = new CountDownLatch(3); for (int i = 0; i < 3; i++) {new Thread(() -> {System.out.println("Task done");latch.countDown();}).start(); } latch.await(); // 等待所有任务完成 System.out.println("All tasks completed");
4.4 使用 CompletableFuture
复制
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 42); future.thenAccept(result -> System.out.println("Result: " + result));
5. JUC 的注意事项
5.1 避免死锁
-
使用锁时注意加锁顺序,避免死锁。
5.2 合理使用线程池
-
根据任务类型选择合适的线程池(如
FixedThreadPool
、CachedThreadPool
)。
5.3 注意资源竞争
-
使用原子类或锁机制避免资源竞争。
6. 总结
-
JUC 是 Java 并发编程的核心模块,提供了丰富的工具类和框架。
-
它支持高性能、灵活的并发编程,适用于高并发数据处理、任务调度、异步编程等场景。
-
掌握 JUC 的使用可以帮助开发者编写高效、线程安全的并发程序。