一、JUC 简介
JUC 即 java.util.concurrent 包,是 Java 5 引入的用于处理并发编程的工具包,极大地简化了 Java 中多线程编程的复杂性,提供了丰富的类和接口,涵盖了线程池、锁机制、并发集合、原子操作等方面,帮助开发者更高效、安全地编写多线程程序。
二、核心组件及使用
1. 线程池(Executor 框架)
线程池是 JUC 中非常重要的一部分,它可以管理和复用线程,避免频繁创建和销毁线程带来的性能开销。主要涉及的类和接口有:
Executor接口:是线程池的基础接口,只定义了一个execute(Runnable command)方法,用于执行提交的任务。ExecutorService接口:继承自Executor接口,扩展了线程池的管理功能,如关闭线程池、提交任务并获取结果等。ThreadPoolExecutor类:是ExecutorService的一个具体实现,通过构造函数可以自定义线程池的各种参数。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPoolExample {
public static void main(String[] args) {
// 创建一个固定大小的线程池
ExecutorService executor = Executors.newFixedThreadPool(5);
for (int i = 0; i < 10; i++) {
final int taskId = i;
executor.execute(() -> {
System.out.println("Task " + taskId + " is running on thread " + Thread.currentThread().getName());
});
}
// 关闭线程池
executor.shutdown();
}
}
2. 锁机制
JUC 提供了多种锁机制,用于解决多线程并发访问共享资源时的同步问题。
ReentrantLock(可重入锁):是一个可重入的互斥锁,与synchronized关键字类似,但功能更强大,支持公平锁和非公平锁,可中断锁等待等。
import java.util.concurrent.locks.ReentrantLock;
public class ReentrantLockExample {
private final ReentrantLock lock = new ReentrantLock();
public void doSomething() {
lock.lock();
try {
// 临界区代码
System.out.println("Thread " + Thread.currentThread().getName() + " is in the critical section.");
} finally {
lock.unlock();
}
}
public static void main(String[] args) {
ReentrantLockExample example = new ReentrantLockExample();
new Thread(example::doSomething).start();
new Thread(example::doSomething).start();
}
}
ReadWriteLock(读写锁):包含一个读锁和一个写锁,允许多个线程同时进行读操作,但写操作是独占的,适用于读多写少的场景。
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class ReadWriteLockExample {
private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
public void read() {
rwLock.readLock().lock();
try {
System.out.println("Thread " + Thread.currentThread().getName() + " is reading.");
} finally {
rwLock.readLock().unlock();
}
}
public void write() {
rwLock.writeLock().lock();
try {
System.out.println("Thread " + Thread.currentThread().getName() + " is writing.");
} finally {
rwLock.writeLock().unlock();
}
}
public static void main(String[] args) {
ReadWriteLockExample example = new ReadWriteLockExample();
new Thread(example::read).start();
new Thread(example::write).start();
}
}
3. 并发集合
JUC 提供了一系列线程安全的并发集合,用于在多线程环境下高效地操作数据。
ConcurrentHashMap:是线程安全的哈希表,采用分段锁或 CAS(Compare-And-Swap)机制实现并发操作,适用于高并发场景。
import java.util.concurrent.ConcurrentHashMap;
public class ConcurrentHashMapExample {
public static void main(String[] args) {
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
map.put("key1", 1);
map.put("key2", 2);
System.out.println(map.get("key1"));
}
}
CopyOnWriteArrayList:是线程安全的列表,在进行写操作时会复制一份原数组,然后在新数组上进行修改,最后将引用指向新数组,适用于读多写少的场景。
import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArrayList;
public class CopyOnWriteArrayListExample {
public static void main(String[] args) {
CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
list.add("element1");
list.add("element2");
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
4. 原子操作类
JUC 提供了一系列原子操作类,位于 java.util.concurrent.atomic 包下,用于实现原子操作,避免多线程环境下的竞态条件。
AtomicInteger:用于对整数进行原子操作,如自增、自减等。
import java.util.concurrent.atomic.AtomicInteger;
public class AtomicIntegerExample {
private static AtomicInteger atomicInteger = new AtomicInteger(0);
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
atomicInteger.incrementAndGet();
}
});
Thread t2 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
atomicInteger.incrementAndGet();
}
});
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(atomicInteger.get());
}
}
5. 同步工具类
JUC 提供了一些同步工具类,用于协调多个线程之间的执行顺序和状态。
CountDownLatch:允许一个或多个线程等待其他线程完成操作后再继续执行。
import java.util.concurrent.CountDownLatch;
public class CountDownLatchExample {
public static void main(String[] args) throws InterruptedException {
int threadCount = 3;
CountDownLatch latch = new CountDownLatch(threadCount);
for (int i = 0; i < threadCount; i++) {
final int taskId = i;
new Thread(() -> {
System.out.println("Task " + taskId + " is running.");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Task " + taskId + " is completed.");
latch.countDown();
}).start();
}
latch.await();
System.out.println("All tasks are completed.");
}
}
CyclicBarrier:允许一组线程相互等待,直到所有线程都到达某个屏障点后再继续执行,并且可以重复使用。
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierExample {
public static void main(String[] args) {
int threadCount = 3;
CyclicBarrier barrier = new CyclicBarrier(threadCount, () -> {
System.out.println("All threads have reached the barrier.");
});
for (int i = 0; i < threadCount; i++) {
final int taskId = i;
new Thread(() -> {
System.out.println("Task " + taskId + " is running.");
try {
Thread.sleep(1000);
barrier.await();
System.out.println("Task " + taskId + " continues after the barrier.");
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
}
}
```。
1146

被折叠的 条评论
为什么被折叠?



