Java并發編程是Java開發中的一個重要領域,而java.util.concurrent(簡稱JUC)包提供了豐富的工具類來簡化并發編程的復雜性。JUC包中的類可以分為幾大類:鎖、原子類、線程池、并發集合、同步工具等。本文將詳細介紹JUC包中的主要工具類及其使用場景。
ReentrantLock是一個可重入的互斥鎖,與synchronized關鍵字類似,但提供了更靈活的鎖機制。ReentrantLock支持公平鎖和非公平鎖,并且可以嘗試獲取鎖、超時獲取鎖、中斷獲取鎖等。
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ReentrantLockExample {
private final Lock lock = new ReentrantLock();
public void performTask() {
lock.lock();
try {
// 臨界區代碼
} finally {
lock.unlock();
}
}
}
ReentrantReadWriteLock是一種讀寫鎖,允許多個讀線程同時訪問共享資源,但在寫線程訪問時,所有讀線程和其他寫線程都會被阻塞。這種鎖適用于讀多寫少的場景。
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class ReentrantReadWriteLockExample {
private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
public void readData() {
rwLock.readLock().lock();
try {
// 讀取共享資源
} finally {
rwLock.readLock().unlock();
}
}
public void writeData() {
rwLock.writeLock().lock();
try {
// 寫入共享資源
} finally {
rwLock.writeLock().unlock();
}
}
}
StampedLock是Java 8引入的一種新的鎖機制,提供了三種模式的鎖:寫鎖、悲觀讀鎖和樂觀讀鎖。StampedLock的性能通常優于ReentrantReadWriteLock,尤其是在讀多寫少的場景下。
import java.util.concurrent.locks.StampedLock;
public class StampedLockExample {
private final StampedLock stampedLock = new StampedLock();
public void readData() {
long stamp = stampedLock.tryOptimisticRead();
// 讀取共享資源
if (!stampedLock.validate(stamp)) {
stamp = stampedLock.readLock();
try {
// 讀取共享資源
} finally {
stampedLock.unlockRead(stamp);
}
}
}
public void writeData() {
long stamp = stampedLock.writeLock();
try {
// 寫入共享資源
} finally {
stampedLock.unlockWrite(stamp);
}
}
}
原子類提供了一種無鎖的線程安全操作,適用于計數器、標志位等場景。JUC包中的原子類包括AtomicInteger、AtomicLong、AtomicBoolean、AtomicReference等。
AtomicInteger是一個可以原子操作的整數類,常用于計數器場景。
import java.util.concurrent.atomic.AtomicInteger;
public class AtomicIntegerExample {
private final AtomicInteger counter = new AtomicInteger(0);
public void increment() {
counter.incrementAndGet();
}
public int getValue() {
return counter.get();
}
}
AtomicReference是一個可以原子操作的引用類型,適用于需要原子更新對象的場景。
import java.util.concurrent.atomic.AtomicReference;
public class AtomicReferenceExample {
private final AtomicReference<String> reference = new AtomicReference<>("initial");
public void updateReference(String newValue) {
reference.set(newValue);
}
public String getReference() {
return reference.get();
}
}
線程池是管理線程的一種機制,可以有效地控制線程的創建、銷毀和復用。JUC包中的ExecutorService接口及其實現類提供了線程池的功能。
ThreadPoolExecutor是線程池的核心實現類,允許開發者自定義線程池的核心線程數、最大線程數、線程存活時間、任務隊列等參數。
import java.util.concurrent.*;
public class ThreadPoolExecutorExample {
public static void main(String[] args) {
ThreadPoolExecutor executor = new ThreadPoolExecutor(
2, // 核心線程數
4, // 最大線程數
60, // 線程存活時間
TimeUnit.SECONDS, // 時間單位
new LinkedBlockingQueue<>() // 任務隊列
);
executor.execute(() -> {
// 執行任務
});
executor.shutdown();
}
}
Executors是一個工具類,提供了創建常用線程池的工廠方法,如newFixedThreadPool、newCachedThreadPool、newSingleThreadExecutor等。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ExecutorsExample {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(4);
executor.execute(() -> {
// 執行任務
});
executor.shutdown();
}
}
JUC包提供了一系列線程安全的集合類,如ConcurrentHashMap、CopyOnWriteArrayList、BlockingQueue等。
ConcurrentHashMap是一個線程安全的哈希表,適用于高并發的場景。與Hashtable相比,ConcurrentHashMap在并發性能上有顯著提升。
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.concurrent.CopyOnWriteArrayList;
public class CopyOnWriteArrayListExample {
public static void main(String[] args) {
CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
list.add("item1");
list.add("item2");
for (String item : list) {
System.out.println(item);
}
}
}
BlockingQueue是一個支持阻塞操作的隊列,常用于生產者-消費者模型。常見的實現類有ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue等。
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
public class BlockingQueueExample {
public static void main(String[] args) throws InterruptedException {
BlockingQueue<String> queue = new LinkedBlockingQueue<>(10);
// 生產者線程
new Thread(() -> {
try {
queue.put("item1");
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
// 消費者線程
new Thread(() -> {
try {
String item = queue.take();
System.out.println(item);
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
JUC包提供了一些同步工具類,如CountDownLatch、CyclicBarrier、Semaphore、Exchanger等,用于控制多個線程之間的同步。
CountDownLatch是一個同步輔助類,允許一個或多個線程等待其他線程完成操作。CountDownLatch的計數器只能遞減,不能重置。
import java.util.concurrent.CountDownLatch;
public class CountDownLatchExample {
public static void main(String[] args) throws InterruptedException {
CountDownLatch latch = new CountDownLatch(3);
for (int i = 0; i < 3; i++) {
new Thread(() -> {
// 執行任務
latch.countDown();
}).start();
}
latch.await(); // 等待所有線程完成任務
System.out.println("所有任務完成");
}
}
CyclicBarrier是一個同步輔助類,允許多個線程相互等待,直到所有線程都到達某個屏障點。與CountDownLatch不同,CyclicBarrier的計數器可以重置。
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierExample {
public static void main(String[] args) {
CyclicBarrier barrier = new CyclicBarrier(3, () -> {
System.out.println("所有線程到達屏障");
});
for (int i = 0; i < 3; i++) {
new Thread(() -> {
try {
// 執行任務
barrier.await();
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
}
}
Semaphore是一個計數信號量,用于控制同時訪問某個資源的線程數量。Semaphore可以用于實現資源池、限流等功能。
import java.util.concurrent.Semaphore;
public class SemaphoreExample {
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(3); // 允許3個線程同時訪問
for (int i = 0; i < 10; i++) {
new Thread(() -> {
try {
semaphore.acquire();
// 訪問資源
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
}
Exchanger是一個同步點,用于兩個線程之間交換數據。Exchanger適用于兩個線程需要相互傳遞數據的場景。
import java.util.concurrent.Exchanger;
public class ExchangerExample {
public static void main(String[] args) {
Exchanger<String> exchanger = new Exchanger<>();
new Thread(() -> {
try {
String data = exchanger.exchange("data1");
System.out.println("線程1收到數據: " + data);
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
new Thread(() -> {
try {
String data = exchanger.exchange("data2");
System.out.println("線程2收到數據: " + data);
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
CompletableFuture是Java 8引入的一個類,用于異步編程。CompletableFuture可以組合多個異步任務,并處理它們的完成結果。
import java.util.concurrent.CompletableFuture;
public class CompletableFutureExample {
public static void main(String[] args) {
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
// 執行異步任務
return "result";
});
future.thenAccept(result -> {
System.out.println("任務完成,結果: " + result);
});
}
}
ForkJoinPool是Java 7引入的一個線程池實現,適用于分治算法的場景。ForkJoinPool使用工作竊取算法來提高并行任務的執行效率。
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
public class ForkJoinPoolExample {
public static void main(String[] args) {
ForkJoinPool pool = new ForkJoinPool();
int result = pool.invoke(new FibonacciTask(10));
System.out.println("Fibonacci(10) = " + result);
}
static class FibonacciTask extends RecursiveTask<Integer> {
private final int n;
FibonacciTask(int n) {
this.n = n;
}
@Override
protected Integer compute() {
if (n <= 1) {
return n;
}
FibonacciTask task1 = new FibonacciTask(n - 1);
task1.fork();
FibonacciTask task2 = new FibonacciTask(n - 2);
return task2.compute() + task1.join();
}
}
}
JUC包提供了豐富的工具類來簡化并發編程的復雜性。通過合理使用這些工具類,開發者可以編寫出高效、安全的并發程序。本文介紹了JUC包中的主要工具類及其使用場景,希望對讀者有所幫助。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。