JUC并发编程与线程安全集合深度解析

105 阅读17分钟

一、JUC(java.util.concurrent)核心类详解

1.1 Callable 与 FutureTask

Callable基础使用

java

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class CallableDemo {
    
    /**
     * Callable与Runnable对比:
     * - Runnable的run()方法没有返回值
     * - Callable的call()方法有返回值,支持泛型,可以抛出异常
     */
    public static void basicCallableUsage() throws ExecutionException, InterruptedException {
        // 创建Callable任务
        Callable<Integer> callable = new Callable<Integer>() {
            @Override
    `        public Integer call() throws Exception {
                System.out.println("Callable任务开始执行...");
                Thread.sleep(2000); // 模拟耗时操作
                int sum = 0;
                for (int i = 1; i <= 100; i++) {
                    sum += i;
                }
                return sum; // 返回计算结果
            }
        };
        
        // 使用FutureTask包装Callable
        FutureTask<Integer> futureTask = new FutureTask<>(callable);
        
        // 创建线程并执行
        Thread thread = new Thread(futureTask);
        thread.start();
        
        System.out.println("主线程继续执行其他任务...");
        
        // 获取任务结果(会阻塞直到任务完成)
        Integer result = futureTask.get();
        System.out.println("计算结果: " + result); // 输出: 5050
    }
    
    /**
     * 带异常处理的Callable
     */
    public static void callableWithException() {
        Callable<String> callable = new Callable<String>() {
            @Override
            public String call() throws Exception {
                if (Math.random() > 0.5) {
                    throw new RuntimeException("随机异常发生!");
                }
                return "任务成功完成";
            }
        };
        
        FutureTask<String> futureTask = new FutureTask<>(callable);
        Thread thread = new Thread(futureTask);
        thread.start();
        
        try {
            String result = futureTask.get();
            System.out.println("结果: " + result);
        } catch (InterruptedException | ExecutionException e) {
            System.err.println("任务执行异常: " + e.getCause().getMessage());
        }
    }
    
    /**
     * 多个Callable任务并行执行
     */
    public static void multipleCallableTasks() throws InterruptedException, ExecutionException {
        Callable<Long> factorialTask = new Callable<Long>() {
            @Override
            public Long call() throws Exception {
                long result = 1;
                for (int i = 1; i <= 10; i++) {
                    result *= i;
                    Thread.sleep(100);
                }
                return result;
            }
        };
        
        Callable<Long> sumTask = new Callable<Long>() {
            @Override
            public Long call() throws Exception {
                long result = 0;
                for (int i = 1; i <= 100; i++) {
                    result += i;
                    Thread.sleep(10);
                }
                return result;
            }
        };
        
        FutureTask<Long> factorialFuture = new FutureTask<>(factorialTask);
        FutureTask<Long> sumFuture = new FutureTask<>(sumTask);
        
        Thread t1 = new Thread(factorialFuture);
        Thread t2 = new Thread(sumFuture);
        
        long startTime = System.currentTimeMillis();
        t1.start();
        t2.start();
        
        // 并行执行,总时间约等于最慢的任务
        Long factorialResult = factorialFuture.get();
        Long sumResult = sumFuture.get();
        long endTime = System.currentTimeMillis();
        
        System.out.println("阶乘结果: " + factorialResult); // 3628800
        System.out.println("累加结果: " + sumResult);       // 5050
        System.out.println("总耗时: " + (endTime - startTime) + "ms");
    }
    
    public static void main(String[] args) throws Exception {
        System.out.println("=== Callable基础使用 ===");
        basicCallableUsage();
        
        System.out.println("\n=== 带异常的Callable ===");
        callableWithException();
        
        System.out.println("\n=== 多个Callable任务 ===");
        multipleCallableTasks();
    }
}

Lambda表达式简化Callable

java

import java.util.concurrent.*;

public class CallableLambda {
    public static void main(String[] args) throws Exception {
        // 使用Lambda表达式简化Callable创建
        Callable<String> callable = () -> {
            Thread.sleep(1000);
            return "Hello from Callable: " + Thread.currentThread().getName();
        };
        
        FutureTask<String> futureTask = new FutureTask<>(callable);
        new Thread(futureTask).start();
        
        System.out.println("主线程做其他事情...");
        String result = futureTask.get();
        System.out.println(result);
        
        // 更简洁的写法
        FutureTask<Integer> simpleTask = new FutureTask<>(() -> {
            int sum = 0;
            for (int i = 0; i < 100; i++) {
                sum += i;
            }
            return sum;
        });
        
        new Thread(simpleTask).start();
        System.out.println("简单任务结果: " + simpleTask.get());
    }
}

1.2 ReentrantLock 深度解析

ReentrantLock 基础使用

java

import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.Condition;

public class ReentrantLockDemo {
    private final ReentrantLock lock = new ReentrantLock();
    private int counter = 0;
    
    /**
     * 基础锁操作
     */
    public void basicLockOperation() {
        lock.lock(); // 获取锁
        try {
            counter++;
            System.out.println(Thread.currentThread().getName() + " - Counter: " + counter);
        } finally {
            lock.unlock(); // 必须在finally中释放锁
        }
    }
    
    /**
     * tryLock() 非阻塞获取锁
     */
    public void tryLockDemo() {
        if (lock.tryLock()) {
            try {
                System.out.println(Thread.currentThread().getName() + " 成功获取锁");
                Thread.sleep(100);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            } finally {
                lock.unlock();
            }
        } else {
            System.out.println(Thread.currentThread().getName() + " 获取锁失败,执行其他操作");
        }
    }
    
    /**
     * 带超时的tryLock
     */
    public void tryLockWithTimeout() {
        try {
            if (lock.tryLock(1, java.util.concurrent.TimeUnit.SECONDS)) {
                try {
                    System.out.println(Thread.currentThread().getName() + " 在超时时间内获取到锁");
                    Thread.sleep(500);
                } finally {
                    lock.unlock();
                }
            } else {
                System.out.println(Thread.currentThread().getName() + " 获取锁超时");
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
    
    /**
     * 公平锁 vs 非公平锁
     */
    public static void fairVsUnfair() throws InterruptedException {
        System.out.println("=== 非公平锁测试 ===");
        testLock(false);
        
        Thread.sleep(1000);
        
        System.out.println("=== 公平锁测试 ===");
        testLock(true);
    }
    
    private static void testLock(boolean fair) throws InterruptedException {
        ReentrantLock lock = new ReentrantLock(fair);
        int threadCount = 5;
        
        for (int i = 0; i < threadCount; i++) {
            final int threadId = i;
            new Thread(() -> {
                lock.lock();
                try {
                    System.out.println("线程" + threadId + "获取到锁");
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                } finally {
                    lock.unlock();
                }
            }).start();
            // 稍微错开启动时间
            Thread.sleep(10);
        }
    }
    
    /**
     * Condition 条件变量 - 生产者消费者模式
     */
    public static void conditionDemo() {
        ReentrantLock lock = new ReentrantLock();
        Condition notFull = lock.newCondition();  // 队列未满条件
        Condition notEmpty = lock.newCondition(); // 队列非空条件
        
        final int capacity = 5;
        int[] queue = new int[capacity];
        int count = 0, putIndex = 0, takeIndex = 0;
        
        // 生产者
        Thread producer = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                lock.lock();
                try {
                    while (count == capacity) {
                        System.out.println("队列已满,生产者等待...");
                        notFull.await();
                    }
                    queue[putIndex] = i;
                    putIndex = (putIndex + 1) % capacity;
                    count++;
                    System.out.println("生产: " + i);
                    notEmpty.signal(); // 唤醒消费者
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                } finally {
                    lock.unlock();
                }
                
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });
        
        // 消费者
        Thread consumer = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                lock.lock();
                try {
                    while (count == 0) {
                        System.out.println("队列为空,消费者等待...");
                        notEmpty.await();
                    }
                    int value = queue[takeIndex];
                    takeIndex = (takeIndex + 1) % capacity;
                    count--;
                    System.out.println("消费: " + value);
                    notFull.signal(); // 唤醒生产者
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                } finally {
                    lock.unlock();
                }
                
                try {
                    Thread.sleep(150);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });
        
        producer.start();
        consumer.start();
    }
    
    public static void main(String[] args) throws Exception {
        ReentrantLockDemo demo = new ReentrantLockDemo();
        
        // 测试基础锁操作
        System.out.println("=== 基础锁操作测试 ===");
        for (int i = 0; i < 5; i++) {
            new Thread(demo::basicLockOperation).start();
        }
        
        Thread.sleep(1000);
        
        // 测试tryLock
        System.out.println("\n=== tryLock测试 ===");
        for (int i = 0; i < 3; i++) {
            new Thread(demo::tryLockDemo).start();
        }
        
        Thread.sleep(1000);
        
        // 测试公平锁
        fairVsUnfair();
        
        // 测试Condition
        System.out.println("\n=== Condition测试 ===");
        conditionDemo();
    }
}

ReentrantLock 与 synchronized 对比

java

public class LockComparison {
    private final Object syncLock = new Object();
    private final ReentrantLock reentrantLock = new ReentrantLock();
    private int syncCounter = 0;
    private int lockCounter = 0;
    
    /**
     * synchronized 方式
     */
    public void incrementSync() {
        synchronized(syncLock) {
            syncCounter++;
            System.out.println("synchronized: " + syncCounter);
        }
    }
    
    /**
     * ReentrantLock 方式
     */
    public void incrementLock() {
        reentrantLock.lock();
        try {
            lockCounter++;
            System.out.println("ReentrantLock: " + lockCounter);
        } finally {
            reentrantLock.unlock();
        }
    }
    
    /**
     * 性能对比测试
     */
    public void performanceTest() throws InterruptedException {
        int threadCount = 10;
        int iterations = 10000;
        
        // 测试synchronized性能
        long syncStart = System.currentTimeMillis();
        Thread[] syncThreads = new Thread[threadCount];
        for (int i = 0; i < threadCount; i++) {
            syncThreads[i] = new Thread(() -> {
                for (int j = 0; j < iterations; j++) {
                    incrementSync();
                }
            });
            syncThreads[i].start();
        }
        for (Thread t : syncThreads) t.join();
        long syncEnd = System.currentTimeMillis();
        
        // 测试ReentrantLock性能
        long lockStart = System.currentTimeMillis();
        Thread[] lockThreads = new Thread[threadCount];
        for (int i = 0; i < threadCount; i++) {
            lockThreads[i] = new Thread(() -> {
                for (int j = 0; j < iterations; j++) {
                    incrementLock();
                }
            });
            lockThreads[i].start();
        }
        for (Thread t : lockThreads) t.join();
        long lockEnd = System.currentTimeMillis();
        
        System.out.println("synchronized 耗时: " + (syncEnd - syncStart) + "ms");
        System.out.println("ReentrantLock 耗时: " + (lockEnd - lockStart) + "ms");
    }
    
    public static void main(String[] args) throws Exception {
        LockComparison comparison = new LockComparison();
        comparison.performanceTest();
    }
}

1.3 线程池深度使用

各种线程池的创建和使用

java

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

public class ThreadPoolDetailed {
    
    /**
     * 1. 固定大小线程池
     */
    public static void fixedThreadPoolDemo() throws InterruptedException {
        System.out.println("=== 固定大小线程池 ===");
        ExecutorService fixedPool = Executors.newFixedThreadPool(3);
        
        for (int i = 0; i < 10; i++) {
            final int taskId = i;
            fixedPool.execute(() -> {
                System.out.println(Thread.currentThread().getName() + " 执行任务 " + taskId);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            });
        }
        
        fixedPool.shutdown();
        fixedPool.awaitTermination(10, TimeUnit.SECONDS);
    }
    
    /**
     * 2. 单线程线程池
     */
    public static void singleThreadPoolDemo() {
        System.out.println("\n=== 单线程线程池 ===");
        ExecutorService singleThreadPool = Executors.newSingleThreadExecutor();
        
        for (int i = 0; i < 5; i++) {
            final int taskId = i;
            singleThreadPool.execute(() -> {
                System.out.println(Thread.currentThread().getName() + " 执行任务 " + taskId);
            });
        }
        
        singleThreadPool.shutdown();
    }
    
    /**
     * 3. 可缓存线程池
     */
    public static void cachedThreadPoolDemo() throws InterruptedException {
        System.out.println("\n=== 可缓存线程池 ===");
        ExecutorService cachedPool = Executors.newCachedThreadPool();
        
        for (int i = 0; i < 10; i++) {
            final int taskId = i;
            cachedPool.execute(() -> {
                System.out.println(Thread.currentThread().getName() + " 执行任务 " + taskId);
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            });
            Thread.sleep(100); // 控制任务提交速度
        }
        
        cachedPool.shutdown();
        cachedPool.awaitTermination(5, TimeUnit.SECONDS);
    }
    
    /**
     * 4. 定时线程池
     */
    public static void scheduledThreadPoolDemo() throws InterruptedException {
        System.out.println("\n=== 定时线程池 ===");
        ScheduledExecutorService scheduledPool = Executors.newScheduledThreadPool(2);
        
        // 延迟执行
        scheduledPool.schedule(() -> {
            System.out.println("延迟3秒执行的任务");
        }, 3, TimeUnit.SECONDS);
        
        // 固定频率执行
        scheduledPool.scheduleAtFixedRate(() -> {
            System.out.println("固定频率任务执行: " + System.currentTimeMillis());
        }, 1, 2, TimeUnit.SECONDS);
        
        // 固定延迟执行
        scheduledPool.scheduleWithFixedDelay(() -> {
            System.out.println("固定延迟任务执行: " + System.currentTimeMillis());
            try {
                Thread.sleep(1000); // 模拟任务执行时间
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }, 1, 2, TimeUnit.SECONDS);
        
        Thread.sleep(10000);
        scheduledPool.shutdown();
    }
    
    /**
     * 5. 自定义线程池
     */
    public static void customThreadPoolDemo() throws InterruptedException {
        System.out.println("\n=== 自定义线程池 ===");
        
        ThreadPoolExecutor customPool = new ThreadPoolExecutor(
            2,                              // 核心线程数
            5,                              // 最大线程数
            60,                             // 空闲线程存活时间
            TimeUnit.SECONDS,               // 时间单位
            new ArrayBlockingQueue<>(10),   // 任务队列
            new CustomThreadFactory(),      // 线程工厂
            new CustomRejectionPolicy()     // 拒绝策略
        );
        
        // 监控线程
        Thread monitor = new Thread(() -> {
            while (!customPool.isTerminated()) {
                System.out.printf("监控: 池大小=%d, 活跃线程=%d, 队列大小=%d, 完成任务=%d%n",
                    customPool.getPoolSize(),
                    customPool.getActiveCount(),
                    customPool.getQueue().size(),
                    customPool.getCompletedTaskCount());
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        });
        monitor.setDaemon(true);
        monitor.start();
        
        // 提交任务
        for (int i = 0; i < 20; i++) {
            final int taskId = i;
            try {
                customPool.execute(() -> {
                    System.out.println(Thread.currentThread().getName() + " 执行任务 " + taskId);
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                });
            } catch (RejectedExecutionException e) {
                System.out.println("任务 " + taskId + " 被拒绝");
            }
            Thread.sleep(100);
        }
        
        customPool.shutdown();
        customPool.awaitTermination(30, TimeUnit.SECONDS);
    }
    
    /**
     * 自定义线程工厂
     */
    static class CustomThreadFactory implements ThreadFactory {
        private final AtomicInteger threadNumber = new AtomicInteger(1);
        
        @Override
        public Thread newThread(Runnable r) {
            Thread thread = new Thread(r, "CustomPool-Thread-" + threadNumber.getAndIncrement());
            thread.setDaemon(false);
            thread.setPriority(Thread.NORM_PRIORITY);
            return thread;
        }
    }
    
    /**
     * 自定义拒绝策略
     */
    static class CustomRejectionPolicy implements RejectedExecutionHandler {
        @Override
        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
            System.err.println("任务被拒绝,执行拒绝策略");
            if (!executor.isShutdown()) {
                // 尝试重新放入队列
                try {
                    executor.getQueue().put(r);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    System.err.println("重新放入队列失败");
                }
            }
        }
    }
    
    public static void main(String[] args) throws Exception {
        fixedThreadPoolDemo();
        singleThreadPoolDemo();
        cachedThreadPoolDemo();
        scheduledThreadPoolDemo();
        customThreadPoolDemo();
    }
}

1.4 信号量 (Semaphore)

Semaphore 详细使用

java

import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

public class SemaphoreDetailed {
    
    /**
     * 基础信号量使用 - 资源池模拟
     */
    public static void basicSemaphore() throws InterruptedException {
        System.out.println("=== 基础信号量 - 数据库连接池模拟 ===");
        
        // 模拟3个数据库连接
        Semaphore connectionPool = new Semaphore(3);
        
        // 创建10个需要数据库连接的线程
        for (int i = 0; i < 10; i++) {
            final int threadId = i;
            new Thread(() -> {
                try {
                    System.out.println("线程 " + threadId + " 等待数据库连接...");
                    connectionPool.acquire(); // 获取许可
                    
                    System.out.println("线程 " + threadId + " 获取到数据库连接,开始操作...");
                    // 模拟数据库操作
                    Thread.sleep(2000);
                    
                    System.out.println("线程 " + threadId + " 释放数据库连接");
                    connectionPool.release(); // 释放许可
                    
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }).start();
            
            Thread.sleep(300); // 控制线程启动间隔
        }
        
        Thread.sleep(10000);
    }
    
    /**
     * 带超时的信号量获取
     */
    public static void semaphoreWithTimeout() throws InterruptedException {
        System.out.println("\n=== 带超时的信号量 ===");
        
        Semaphore semaphore = new Semaphore(2);
        
        for (int i = 0; i < 5; i++) {
            final int threadId = i;
            new Thread(() -> {
                try {
                    System.out.println("线程 " + threadId + " 尝试获取信号量...");
                    
                    // 尝试在1秒内获取信号量
                    if (semaphore.tryAcquire(1, TimeUnit.SECONDS)) {
                        try {
                            System.out.println("线程 " + threadId + " 成功获取信号量");
                            Thread.sleep(1500); // 模拟工作
                        } finally {
                            semaphore.release();
                            System.out.println("线程 " + threadId + " 释放信号量");
                        }
                    } else {
                        System.out.println("线程 " + threadId + " 获取信号量超时");
                    }
                    
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }).start();
        }
        
        Thread.sleep(8000);
    }
    
    /**
     * 多资源类型的信号量
     */
    public static void multipleResourceSemaphore() throws InterruptedException {
        System.out.println("\n=== 多资源类型信号量 ===");
        
        // 模拟两种资源:CPU核心和内存块
        Semaphore cpuCores = new Semaphore(2);    // 2个CPU核心
        Semaphore memoryBlocks = new Semaphore(3); // 3个内存块
        
        for (int i = 0; i < 6; i++) {
            final int taskId = i;
            new Thread(() -> {
                try {
                    System.out.println("任务 " + taskId + " 申请资源...");
                    
                    // 同时申请两种资源
                    cpuCores.acquire();
                    memoryBlocks.acquire();
                    
                    System.out.println("任务 " + taskId + " 获得所有资源,开始执行...");
                    Thread.sleep(1000); // 模拟任务执行
                    
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                } finally {
                    memoryBlocks.release();
                    cpuCores.release();
                    System.out.println("任务 " + taskId + " 释放所有资源");
                }
            }).start();
        }
        
        Thread.sleep(8000);
    }
    
    /**
     * 信号量实现生产者消费者
     */
    public static void semaphoreProducerConsumer() throws InterruptedException {
        System.out.println("\n=== 信号量实现生产者消费者 ===");
        
        final int bufferSize = 5;
        int[] buffer = new int[bufferSize];
        int in = 0, out = 0;
        
        Semaphore mutex = new Semaphore(1);        // 互斥信号量
        Semaphore empty = new Semaphore(bufferSize); // 空槽位信号量
        Semaphore full = new Semaphore(0);         // 满槽位信号量
        
        // 生产者
        Thread producer = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    empty.acquire(); // 等待空槽位
                    mutex.acquire(); // 获取互斥锁
                    
                    // 生产数据
                    buffer[in] = i;
                    System.out.println("生产: " + i + " 到位置 " + in);
                    in = (in + 1) % bufferSize;
                    
                    mutex.release(); // 释放互斥锁
                    full.release();  // 增加满槽位
                    
                    Thread.sleep(100);
                    
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });
        
        // 消费者
        Thread consumer = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    full.acquire();  // 等待满槽位
                    mutex.acquire(); // 获取互斥锁
                    
                    // 消费数据
                    int value = buffer[out];
                    System.out.println("消费: " + value + " 从位置 " + out);
                    out = (out + 1) % bufferSize;
                    
                    mutex.release(); // 释放互斥锁
                    empty.release(); // 增加空槽位
                    
                    Thread.sleep(150);
                    
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });
        
        producer.start();
        consumer.start();
        
        producer.join();
        consumer.join();
    }
    
    public static void main(String[] args) throws Exception {
        basicSemaphore();
        semaphoreWithTimeout();
        multipleResourceSemaphore();
        semaphoreProducerConsumer();
    }
}

1.5 CountDownLatch 详细使用

CountDownLatch 应用场景

java

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadLocalRandom;

public class CountDownLatchDetailed {
    
    /**
     * 场景1:多任务并行执行,主线程等待所有任务完成
     */
    public static void parallelTasks() throws InterruptedException {
        System.out.println("=== 并行任务执行 ===");
        
        int taskCount = 5;
        CountDownLatch latch = new CountDownLatch(taskCount);
        
        for (int i = 0; i < taskCount; i++) {
            final int taskId = i;
            new Thread(() -> {
                try {
                    // 模拟任务执行时间
                    int sleepTime = ThreadLocalRandom.current().nextInt(1000, 3000);
                    Thread.sleep(sleepTime);
                    System.out.println("任务 " + taskId + " 完成,耗时 " + sleepTime + "ms");
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                } finally {
                    latch.countDown(); // 任务完成,计数器减1
                }
            }).start();
        }
        
        System.out.println("主线程等待所有任务完成...");
        latch.await(); // 阻塞直到计数器为0
        System.out.println("所有任务已完成,主线程继续执行");
    }
    
    /**
     * 场景2:比赛开始信号
     */
    public static void raceStart() throws InterruptedException {
        System.out.println("\n=== 比赛开始信号 ===");
        
        int runnerCount = 4;
        CountDownLatch startSignal = new CountDownLatch(1);
        CountDownLatch finishSignal = new CountDownLatch(runnerCount);
        
        // 运动员线程
        for (int i = 0; i < runnerCount; i++) {
            final int runnerId = i;
            new Thread(() -> {
                try {
                    System.out.println("运动员 " + runnerId + " 准备就绪,等待发令枪...");
                    startSignal.await(); // 等待发令枪响
                    
                    // 开始跑步
                    System.out.println("运动员 " + runnerId + " 起跑!");
                    Thread.sleep(ThreadLocalRandom.current().nextInt(1000, 5000));
                    System.out.println("运动员 " + runnerId + " 到达终点");
                    
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                } finally {
                    finishSignal.countDown();
                }
            }).start();
        }
        
        // 裁判线程
        Thread.sleep(2000); // 裁判准备时间
        System.out.println("预备...砰!");
        startSignal.countDown(); // 发令枪响
        
        finishSignal.await(); // 等待所有运动员到达终点
        System.out.println("比赛结束!");
    }
    
    /**
     * 场景3:多阶段任务
     */
    public static void multiPhaseTasks() throws InterruptedException {
        System.out.println("\n=== 多阶段任务 ===");
        
        int phase1Tasks = 3;
        int phase2Tasks = 2;
        
        CountDownLatch phase1Latch = new CountDownLatch(phase1Tasks);
        CountDownLatch phase2Latch = new CountDownLatch(phase2Tasks);
        
        // 第一阶段任务
        for (int i = 0; i < phase1Tasks; i++) {
            final int taskId = i;
            new Thread(() -> {
                try {
                    System.out.println("第一阶段任务 " + taskId + " 开始");
                    Thread.sleep(1000 + taskId * 500);
                    System.out.println("第一阶段任务 " + taskId + " 完成");
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                } finally {
                    phase1Latch.countDown();
                }
            }).start();
        }
        
        // 等待第一阶段完成
        phase1Latch.await();
        System.out.println("=== 第一阶段所有任务完成,开始第二阶段 ===");
        
        // 第二阶段任务
        for (int i = 0; i < phase2Tasks; i++) {
            final int taskId = i;
            new Thread(() -> {
                try {
                    System.out.println("第二阶段任务 " + taskId + " 开始");
                    Thread.sleep(1500 + taskId * 500);
                    System.out.println("第二阶段任务 " + taskId + " 完成");
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                } finally {
                    phase2Latch.countDown();
                }
            }).start();
        }
        
        // 等待第二阶段完成
        phase2Latch.await();
        System.out.println("=== 所有阶段任务完成 ===");
    }
    
    /**
     * 场景4:带超时的等待
     */
    public static void timeoutWait() throws InterruptedException {
        System.out.println("\n=== 带超时的等待 ===");
        
        CountDownLatch latch = new CountDownLatch(3);
        
        // 两个正常完成的任务
        for (int i = 0; i < 2; i++) {
            final int taskId = i;
            new Thread(() -> {
                try {
                    Thread.sleep(1000);
                    System.out.println("任务 " + taskId + " 正常完成");
                    latch.countDown();
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }).start();
        }
        
        // 一个超时任务
        new Thread(() -> {
            try {
                Thread.sleep(5000); // 这个任务会超时
                System.out.println("超时任务完成");
                latch.countDown();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }).start();
        
        // 主线程最多等待3秒
        boolean completed = latch.await(3, TimeUnit.SECONDS);
        if (completed) {
            System.out.println("所有任务在超时前完成");
        } else {
            System.out.println("等待超时,还有 " + latch.getCount() + " 个任务未完成");
        }
    }
    
    public static void main(String[] args) throws Exception {
        parallelTasks();
        raceStart();
        multiPhaseTasks();
        timeoutWait();
    }
}

二、线程安全的集合类

2.1 多线程环境下的 List

各种线程安全List对比

java

import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;

public class ThreadSafeListDemo {
    
    /**
     * 1. 手动加锁的ArrayList
     */
    public static void manualSynchronizedArrayList() throws InterruptedException {
        System.out.println("=== 手动加锁的ArrayList ===");
        
        List<Integer> list = new ArrayList<>();
        Object lock = new Object();
        int threadCount = 10;
        int operationsPerThread = 1000;
        CountDownLatch latch = new CountDownLatch(threadCount);
        
        long startTime = System.currentTimeMillis();
        
        for (int i = 0; i < threadCount; i++) {
            final int threadId = i;
            new Thread(() -> {
                for (int j = 0; j < operationsPerThread; j++) {
                    synchronized(lock) {
                        list.add(threadId * operationsPerThread + j);
                    }
                }
                latch.countDown();
            }).start();
        }
        
        latch.await();
        long endTime = System.currentTimeMillis();
        
        System.out.println("手动加锁ArrayList大小: " + list.size());
        System.out.println("耗时: " + (endTime - startTime) + "ms");
    }
    
    /**
     * 2. Collections.synchronizedList
     */
    public static void synchronizedListWrapper() throws InterruptedException {
        System.out.println("\n=== Collections.synchronizedList ===");
        
        List<Integer> list = Collections.synchronizedList(new ArrayList<>());
        int threadCount = 10;
        int operationsPerThread = 1000;
        CountDownLatch latch = new CountDownLatch(threadCount);
        
        long startTime = System.currentTimeMillis();
        
        for (int i = 0; i < threadCount; i++) {
            final int threadId = i;
            new Thread(() -> {
                for (int j = 0; j < operationsPerThread; j++) {
                    list.add(threadId * operationsPerThread + j);
                }
                latch.countDown();
            }).start();
        }
        
        latch.await();
        long endTime = System.currentTimeMillis();
        
        System.out.println("synchronizedList大小: " + list.size());
        System.out.println("耗时: " + (endTime - startTime) + "ms");
    }
    
    /**
     * 3. CopyOnWriteArrayList
     */
    public static void copyOnWriteArrayListDemo() throws InterruptedException {
        System.out.println("\n=== CopyOnWriteArrayList ===");
        
        CopyOnWriteArrayList<Integer> list = new CopyOnWriteArrayList<>();
        int threadCount = 10;
        int operationsPerThread = 1000;
        CountDownLatch latch = new CountDownLatch(threadCount);
        
        long startTime = System.currentTimeMillis();
        
        for (int i = 0; i < threadCount; i++) {
            final int threadId = i;
            new Thread(() -> {
                for (int j = 0; j < operationsPerThread; j++) {
                    list.add(threadId * operationsPerThread + j);
                }
                latch.countDown();
            }).start();
        }
        
        latch.await();
        long endTime = System.currentTimeMillis();
        
        System.out.println("CopyOnWriteArrayList大小: " + list.size());
        System.out.println("耗时: " + (endTime - startTime) + "ms");
    }
    
    /**
     * CopyOnWriteArrayList 适用场景演示
     */
    public static void copyOnWriteSuitableScenario() throws InterruptedException {
        System.out.println("\n=== CopyOnWriteArrayList 适用场景 ===");
        
        CopyOnWriteArrayList<String> configList = new CopyOnWriteArrayList<>();
        
        // 初始化配置
        configList.add("server.port=8080");
        configList.add("database.url=jdbc:mysql://localhost:3306/test");
        configList.add("cache.enabled=true");
        
        // 多个读取线程
        for (int i = 0; i < 5; i++) {
            new Thread(() -> {
                while (true) {
                    // 读取操作很快,不需要加锁
                    for (String config : configList) {
                        // 模拟读取配置
                    }
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                        break;
                    }
                }
            }).start();
        }
        
        // 配置更新线程(很少发生)
        Thread configUpdater = new Thread(() -> {
            try {
                Thread.sleep(2000);
                System.out.println("开始更新配置...");
                
                // 创建新的配置列表
                CopyOnWriteArrayList<String> newConfig = new CopyOnWriteArrayList<>();
                newConfig.add("server.port=8081"); // 修改端口
                newConfig.add("database.url=jdbc:mysql://localhost:3306/prod"); // 修改数据库
                newConfig.add("cache.enabled=false"); // 修改缓存设置
                newConfig.add("new.feature=true"); // 新增配置
                
                // 替换整个配置列表
                configList.clear();
                configList.addAll(newConfig);
                
                System.out.println("配置更新完成");
                
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });
        
        configUpdater.start();
        configUpdater.join();
        
        System.out.println("最终配置: " + configList);
    }
    
    /**
     * 性能对比测试
     */
    public static void performanceComparison() throws InterruptedException {
        System.out.println("\n=== 性能对比测试 ===");
        
        int threadCount = 20;
        int operationsPerThread = 1000;
        
        // 测试手动加锁ArrayList
        List<Integer> manualList = new ArrayList<>();
        Object lock = new Object();
        CountDownLatch latch1 = new CountDownLatch(threadCount);
        
        long start1 = System.currentTimeMillis();
        for (int i = 0; i < threadCount; i++) {
            new Thread(() -> {
                for (int j = 0; j < operationsPerThread; j++) {
                    synchronized(lock) {
                        manualList.add(j);
                    }
                }
                latch1.countDown();
            }).start();
        }
        latch1.await();
        long end1 = System.currentTimeMillis();
        
        // 测试synchronizedList
        List<Integer> syncList = Collections.synchronizedList(new ArrayList<>());
        CountDownLatch latch2 = new CountDownLatch(threadCount);
        
        long start2 = System.currentTimeMillis();
        for (int i = 0; i < threadCount; i++) {
            new Thread(() -> {
                for (int j = 0; j < operationsPerThread; j++) {
                    syncList.add(j);
                }
                latch2.countDown();
            }).start();
        }
        latch2.await();
        long end2 = System.currentTimeMillis();
        
        // 测试CopyOnWriteArrayList
        CopyOnWriteArrayList<Integer> cowList = new CopyOnWriteArrayList<>();
        CountDownLatch latch3 = new CountDownLatch(threadCount);
        
        long start3 = System.currentTimeMillis();
        for (int i = 0; i < threadCount; i++) {
            new Thread(() -> {
                for (int j = 0; j < operationsPerThread; j++) {
                    cowList.add(j);
                }
                latch3.countDown();
            }).start();
        }
        latch3.await();
        long end3 = System.currentTimeMillis();
        
        System.out.println("手动加锁ArrayList: " + (end1 - start1) + "ms");
        System.out.println("synchronizedList: " + (end2 - start2) + "ms");
        System.out.println("CopyOnWriteArrayList: " + (end3 - start3) + "ms");
    }
    
    public static void main(String[] args) throws Exception {
        manualSynchronizedArrayList();
        synchronizedListWrapper();
        copyOnWriteArrayListDemo();
        copyOnWriteSuitableScenario();
        performanceComparison();
    }
}

2.2 多线程环境下的队列

各种阻塞队列对比

java

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

public class ThreadSafeQueueDemo {
    
    /**
     * 1. ArrayBlockingQueue - 有界阻塞队列
     */
    public static void arrayBlockingQueueDemo() throws InterruptedException {
        System.out.println("=== ArrayBlockingQueue ===");
        
        ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<>(5);
        
        // 生产者
        Thread producer = new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    queue.put(i); // 如果队列满则阻塞
                    System.out.println("生产: " + i + " 队列大小: " + queue.size());
                    Thread.sleep(100);
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });
        
        // 消费者
        Thread consumer = new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    Integer value = queue.take(); // 如果队列空则阻塞
                    System.out.println("消费: " + value + " 队列大小: " + queue.size());
                    Thread.sleep(200);
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });
        
        producer.start();
        consumer.start();
        
        producer.join();
        consumer.join();
    }
    
    /**
     * 2. LinkedBlockingQueue - 可选的边界阻塞队列
     */
    public static void linkedBlockingQueueDemo() throws InterruptedException {
        System.out.println("\n=== LinkedBlockingQueue ===");
        
        // 无界队列
        LinkedBlockingQueue<Integer> unboundedQueue = new LinkedBlockingQueue<>();
        
        // 有界队列
        LinkedBlockingQueue<Integer> boundedQueue = new LinkedBlockingQueue<>(3);
        
        // 测试有界队列的生产者消费者
        Thread producer = new Thread(() -> {
            try {
                for (int i = 0; i < 6; i++) {
                    boolean success = boundedQueue.offer(i, 1, TimeUnit.SECONDS);
                    if (success) {
                        System.out.println("生产: " + i + " 成功");
                    } else {
                        System.out.println("生产: " + i + " 超时");
                    }
                    Thread.sleep(300);
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });
        
        Thread consumer = new Thread(() -> {
            try {
                for (int i = 0; i < 6; i++) {
                    Integer value = boundedQueue.poll(2, TimeUnit.SECONDS);
                    if (value != null) {
                        System.out.println("消费: " + value + " 成功");
                    } else {
                        System.out.println("消费超时");
                    }
                    Thread.sleep(500);
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });
        
        producer.start();
        consumer.start();
        
        producer.join();
        consumer.join();
    }
    
    /**
     * 3. PriorityBlockingQueue - 带优先级的阻塞队列
     */
    public static void priorityBlockingQueueDemo() throws InterruptedException {
        System.out.println("\n=== PriorityBlockingQueue ===");
        
        PriorityBlockingQueue<Integer> priorityQueue = new PriorityBlockingQueue<>();
        
        // 生产者 - 插入无序数据
        Thread producer = new Thread(() -> {
            int[] data = {5, 1, 8, 3, 9, 2};
            for (int value : data) {
                priorityQueue.put(value);
                System.out.println("插入: " + value);
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });
        
        // 消费者 - 按优先级取出
        Thread consumer = new Thread(() -> {
            for (int i = 0; i < 6; i++) {
                try {
                    Integer value = priorityQueue.take();
                    System.out.println("取出: " + value + " (队列大小: " + priorityQueue.size() + ")");
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });
        
        producer.start();
        consumer.start();
        
        producer.join();
        consumer.join();
    }
    
    /**
     * 4. SynchronousQueue - 不存储元素的阻塞队列
     */
    public static void synchronousQueueDemo() throws InterruptedException {
        System.out.println("\n=== SynchronousQueue ===");
        
        SynchronousQueue<Integer> syncQueue = new SynchronousQueue<>(true); // 公平模式
        
        AtomicInteger produced = new AtomicInteger(0);
        AtomicInteger consumed = new AtomicInteger(0);
        
        // 生产者
        Thread producer = new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                try {
                    System.out.println("生产者尝试传递: " + i);
                    syncQueue.put(i);
                    produced.incrementAndGet();
                    System.out.println("生产者成功传递: " + i);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });
        
        // 消费者
        Thread consumer = new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                try {
                    System.out.println("消费者等待接收...");
                    Integer value = syncQueue.take();
                    consumed.incrementAndGet();
                    System.out.println("消费者接收到: " + value);
                    Thread.sleep(1000); // 模拟处理时间
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });
        
        producer.start();
        consumer.start();
        
        producer.join();
        consumer.join();
        
        System.out.println("生产数量: " + produced.get() + ", 消费数量: " + consumed.get());
    }
    
    /**
     * 5. 延迟队列 DelayQueue
     */
    public static void delayQueueDemo() throws InterruptedException {
        System.out.println("\n=== DelayQueue ===");
        
        DelayQueue<DelayedTask> delayQueue = new DelayQueue<>();
        
        // 添加延迟任务
        long now = System.currentTimeMillis();
        delayQueue.put(new DelayedTask("任务1", now + 3000)); // 3秒后执行
        delayQueue.put(new DelayedTask("任务2", now + 1000)); // 1秒后执行
        delayQueue.put(new DelayedTask("任务3", now + 5000)); // 5秒后执行
        
        System.out.println("开始等待延迟任务...");
        
        while (!delayQueue.isEmpty()) {
            DelayedTask task = delayQueue.take();
            System.out.println("执行: " + task);
        }
        
        System.out.println("所有延迟任务执行完成");
    }
    
    static class DelayedTask implements Delayed {
        private final String name;
        private final long executeTime;
        
        public DelayedTask(String name, long executeTime) {
            this.name = name;
            this.executeTime = executeTime;
        }
        
        @Override
        public long getDelay(TimeUnit unit) {
            long diff = executeTime - System.currentTimeMillis();
            return unit.convert(diff, TimeUnit.MILLISECONDS);
        }
        
        @Override
        public int compareTo(Delayed other) {
            if (this.executeTime < ((DelayedTask) other).executeTime) {
                return -1;
            }
            if (this.executeTime > ((DelayedTask) other).executeTime) {
                return 1;
            }
            return 0;
        }
        
        @Override
        public String toString() {
            return "DelayedTask{" + "name='" + name + ''' + 
                   ", executeTime=" + executeTime + '}';
        }
    }
    
    public static void main(String[] args) throws Exception {
        arrayBlockingQueueDemo();
        linkedBlockingQueueDemo();
        priorityBlockingQueueDemo();
        synchronousQueueDemo();
        delayQueueDemo();
    }
}

2.3 多线程环境下的哈希表

ConcurrentHashMap 深度解析

java

import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

public class ConcurrentHashMapDemo {
    
    /**
     * ConcurrentHashMap 基础操作
     */
    public static void basicOperations() {
        System.out.println("=== ConcurrentHashMap 基础操作 ===");
        
        ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
        
        // 并发安全的put操作
        map.put("key1", 1);
        map.put("key2", 2);
        map.put("key3", 3);
        
        // 如果不存在则添加
        map.putIfAbsent("key1", 100); // 不会替换,因为key1已存在
        map.putIfAbsent("key4", 4);   // 会添加,因为key4不存在
        
        // 原子操作
        map.compute("key1", (k, v) -> v == null ? 1 : v + 1); // key1的值+1
        map.merge("key2", 10, (oldVal, newVal) -> oldVal + newVal); // 合并
        
        System.out.println("Map内容: " + map);
    }
    
    /**
     * 并发性能测试
     */
    public static void performanceTest() throws InterruptedException {
        System.out.println("\n=== 并发性能测试 ===");
        
        int threadCount = 10;
        int operationsPerThread = 10000;
        
        // 测试ConcurrentHashMap
        ConcurrentHashMap<Integer, String> concurrentMap = new ConcurrentHashMap<>();
        CountDownLatch latch1 = new CountDownLatch(threadCount);
        
        long start1 = System.currentTimeMillis();
        for (int i = 0; i < threadCount; i++) {
            final int threadId = i;
            new Thread(() -> {
                for (int j = 0; j < operationsPerThread; j++) {
                    concurrentMap.put(threadId * operationsPerThread + j, "value");
                }
                latch1.countDown();
            }).start();
        }
        latch1.await();
        long end1 = System.currentTimeMillis();
        
        // 测试Hashtable
        Hashtable<Integer, String> hashtable = new Hashtable<>();
        CountDownLatch latch2 = new CountDownLatch(threadCount);
        
        long start2 = System.currentTimeMillis();
        for (int i = 0; i < threadCount; i++) {
            final int threadId = i;
            new Thread(() -> {
                for (int j = 0; j < operationsPerThread; j++) {
                    hashtable.put(threadId * operationsPerThread + j, "value");
                }
                latch2.countDown();
            }).start();
        }
        latch2.await();
        long end2 = System.currentTimeMillis();
        
        // 测试Collections.synchronizedMap
        Map<Integer, String> synchronizedMap = Collections.synchronizedMap(new HashMap<>());
        CountDownLatch latch3 = new CountDownLatch(threadCount);
        
        long start3 = System.currentTimeMillis();
        for (int i = 0; i < threadCount; i++) {
            final int threadId = i;
            new Thread(() -> {
                for (int j = 0; j < operationsPerThread; j++) {
                    synchronizedMap.put(threadId * operationsPerThread + j, "value");
                }
                latch3.countDown();
            }).start();
        }
        latch3.await();
        long end3 = System.currentTimeMillis();
        
        System.out.println("ConcurrentHashMap 耗时: " + (end1 - start1) + "ms");
        System.out.println("Hashtable 耗时: " + (end2 - start2) + "ms");
        System.out.println("synchronizedMap 耗时: " + (end3 - start3) + "ms");
    }
    
    /**
     * ConcurrentHashMap 高级特性
     */
    public static void advancedFeatures() {
        System.out.println("\n=== ConcurrentHashMap 高级特性 ===");
        
        ConcurrentHashMap<String, AtomicInteger> wordCountMap = new ConcurrentHashMap<>();
        
        // 模拟文本处理
        String[] documents = {
            "hello world java concurrent",
            "java programming is fun",
            "concurrent programming in java",
            "hello java world"
        };
        
        // 并行处理文档
        Arrays.stream(documents)
              .parallel()
              .forEach(document -> {
                  String[] words = document.split(" ");
                  for (String word : words) {
                      // 原子更新
                      wordCountMap.compute(word, (k, v) -> {
                          if (v == null) {
                              return new AtomicInteger(1);
                          } else {
                              v.incrementAndGet();
                              return v;
                          }
                      });
                  }
              });
        
        System.out.println("词频统计: " + wordCountMap);
        
        // 搜索操作
        long count = wordCountMap.search(2, (key, value) -> 
            value.get() > 2 ? key : null
        );
        System.out.println("出现超过2次的单词: " + (count != null ? count : "无"));
        
        // 归约操作
        int totalWords = wordCountMap.reduceValues(2, 
            value -> value.get(), 
            Integer::sum
        );
        System.out.println("总单词数: " + totalWords);
    }
    
    /**
     * 分段锁机制演示
     */
    public static void segmentLockDemo() throws InterruptedException {
        System.out.println("\n=== 分段锁机制演示 ===");
        
        ConcurrentHashMap<Integer, String> map = new ConcurrentHashMap<>();
        
        // 不同分段的键(通过哈希计算分布在不同的段)
        int[] keysInDifferentSegments = {1, 2, 17, 18, 33, 34}; // 假设这些键在不同段
        
        CountDownLatch latch = new CountDownLatch(keysInDifferentSegments.length);
        
        long startTime = System.currentTimeMillis();
        
        for (int key : keysInDifferentSegments) {
            new Thread(() -> {
                // 模拟对同一个段的操作会竞争,不同段的操作不会竞争
                for (int i = 0; i < 1000; i++) {
                    map.put(key, "value" + i);
                }
                latch.countDown();
            }).start();
        }
        
        latch.await();
        long endTime = System.currentTimeMillis();
        
        System.out.println("分段操作耗时: " + (endTime - startTime) + "ms");
        System.out.println("最终Map大小: " + map.size());
    }
    
    /**
     * ConcurrentHashMap 在Java 8中的改进
     */
    public static void java8Improvements() {
        System.out.println("\n=== Java 8+ 改进特性 ===");
        
        ConcurrentHashMap<String, Long> map = new ConcurrentHashMap<>();
        
        // 初始化一些数据
        map.put("A", 1L);
        map.put("B", 2L);
        map.put("C", 3L);
        
        // forEach - 并行遍历
        System.out.println("并行遍历:");
        map.forEach(2, (k, v) -> System.out.println(k + " -> " + v));
        
        // reduce - 并行归约
        Long sum = map.reduceValues(2, Long::sum);
        System.out.println("值总和: " + sum);
        
        // mappingCount - 返回long类型的映射数量
        System.out.println("映射数量: " + map.mappingCount());
        
        // 新方法: getOrDefault, putIfAbsent, computeIfAbsent等
        Long value = map.getOrDefault("D", 0L);
        System.out.println("获取D的值(默认0): " + value);
        
        map.computeIfAbsent("D", k -> 4L);
        System.out.println("计算后D的值: " + map.get("D"));
    }
    
    public static void main(String[] args) throws Exception {
        basicOperations();
        performanceTest();
        advancedFeatures();
        segmentLockDemo();
        java8Improvements();
    }
}

总结

核心知识点回顾:

  1. JUC核心类

    • Callable/FutureTask:带返回值的任务执行
    • ReentrantLock:更灵活的锁机制,支持公平锁、Condition等
    • 线程池:合理管理线程资源,提高性能
    • Semaphore:控制资源访问的并发数
    • CountDownLatch:多线程协调工具
  2. 线程安全集合

    • CopyOnWriteArrayList:读多写少场景,无锁读取
    • 各种BlockingQueue:生产者消费者模式的最佳选择
    • ConcurrentHashMap:分段锁机制,高并发性能优秀
  3. 选型建议

    • 根据读写比例选择合适的数据结构
    • 考虑数据一致性和性能的平衡
    • 合理使用并发工具类简化多线程编程
  4. 最佳实践

    • 理解各种工具的适用场景
    • 注意资源管理和异常处理
    • 进行充分的性能测试和监控

这些工具类和集合为构建高性能、高并发的Java应用程序提供了强大的支持。