Java并发编程最佳实践

# Java并发编程最佳实践

# 1. 并发编程原则

# 1.1 核心原则

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

public class ConcurrencyPrinciplesDemo {
    
    // 原则1:不可变对象是线程安全的
    public static final class ImmutablePoint {
        private final int x;
        private final int y;
        
        public ImmutablePoint(int x, int y) {
            this.x = x;
            this.y = y;
        }
        
        public int getX() { return x; }
        public int getY() { return y; }
        
        public ImmutablePoint move(int deltaX, int deltaY) {
            return new ImmutablePoint(x + deltaX, y + deltaY);
        }
        
        @Override
        public String toString() {
            return "Point(" + x + ", " + y + ")";
        }
    }
    
    // 原则2:最小化共享状态
    public static class TaskProcessor {
        private final AtomicInteger processedCount = new AtomicInteger(0);
        
        public void processTask(String taskData) {
            // 使用局部变量,避免共享状态
            String processedData = doProcess(taskData);
            
            // 只在必要时更新共享状态
            processedCount.incrementAndGet();
            
            System.out.println("处理完成: " + processedData + 
                             ", 总计: " + processedCount.get());
        }
        
        private String doProcess(String data) {
            // 模拟处理过程
            return "Processed: " + data;
        }
        
        public int getProcessedCount() {
            return processedCount.get();
        }
    }
    
    // 原则3:使用线程安全的数据结构
    public static void demonstrateThreadSafeCollections() {
        System.out.println("=== 线程安全集合演示 ===");
        
        // 使用ConcurrentHashMap而不是HashMap
        ConcurrentHashMap<String, Integer> safeMap = new ConcurrentHashMap<>();
        
        // 使用BlockingQueue进行线程间通信
        BlockingQueue<String> queue = new ArrayBlockingQueue<>(10);
        
        ExecutorService executor = Executors.newFixedThreadPool(3);
        
        // 生产者
        executor.submit(() -> {
            for (int i = 0; i < 5; i++) {
                try {
                    String item = "Item-" + i;
                    queue.put(item);
                    safeMap.put(item, i);
                    System.out.println("生产: " + item);
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });
        
        // 消费者
        executor.submit(() -> {
            for (int i = 0; i < 5; i++) {
                try {
                    String item = queue.take();
                    Integer value = safeMap.get(item);
                    System.out.println("消费: " + item + ", 值: " + value);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });
        
        executor.shutdown();
        try {
            executor.awaitTermination(5, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    
    public static void main(String[] args) {
        // 演示不可变对象
        ImmutablePoint point = new ImmutablePoint(1, 2);
        ImmutablePoint newPoint = point.move(3, 4);
        System.out.println("原点: " + point + ", 新点: " + newPoint);
        
        // 演示最小化共享状态
        TaskProcessor processor = new TaskProcessor();
        ExecutorService executor = Executors.newFixedThreadPool(3);
        
        for (int i = 0; i < 5; i++) {
            final String taskData = "Task-" + i;
            executor.submit(() -> processor.processTask(taskData));
        }
        
        executor.shutdown();
        try {
            executor.awaitTermination(2, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        demonstrateThreadSafeCollections();
    }
}

# 2. 锁的最佳实践

# 2.1 锁的使用原则

import java.util.concurrent.locks.*;
import java.util.concurrent.TimeUnit;
import java.util.*;

public class LockingBestPractices {
    
    // 实践1:缩小锁的范围
    public static class OptimizedCounter {
        private final Object lock = new Object();
        private int count = 0;
        
        // 不好的做法:锁的范围太大
        public void badIncrement() {
            synchronized (lock) {
                // 耗时的非关键操作
                doSomeExpensiveWork();
                count++;
                // 更多非关键操作
                doMoreWork();
            }
        }
        
        // 好的做法:只锁关键部分
        public void goodIncrement() {
            // 非关键操作在锁外执行
            doSomeExpensiveWork();
            
            synchronized (lock) {
                count++; // 只锁必要的操作
            }
            
            doMoreWork();
        }
        
        public int getCount() {
            synchronized (lock) {
                return count;
            }
        }
        
        private void doSomeExpensiveWork() {
            // 模拟耗时操作
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
        
        private void doMoreWork() {
            // 模拟其他工作
        }
    }
    
    // 实践2:避免锁嵌套,防止死锁
    public static class DeadlockAvoidance {
        private final Object lock1 = new Object();
        private final Object lock2 = new Object();
        
        // 危险:可能导致死锁
        public void dangerousMethod1() {
            synchronized (lock1) {
                System.out.println("获得lock1");
                synchronized (lock2) {
                    System.out.println("获得lock2");
                    // 执行操作
                }
            }
        }
        
        public void dangerousMethod2() {
            synchronized (lock2) {
                System.out.println("获得lock2");
                synchronized (lock1) {
                    System.out.println("获得lock1");
                    // 执行操作
                }
            }
        }
        
        // 安全:使用固定的锁顺序
        private final Object firstLock = lock1;
        private final Object secondLock = lock2;
        
        public void safeMethod1() {
            synchronized (firstLock) {
                synchronized (secondLock) {
                    // 执行操作
                    System.out.println("安全方法1执行");
                }
            }
        }
        
        public void safeMethod2() {
            synchronized (firstLock) {
                synchronized (secondLock) {
                    // 执行操作
                    System.out.println("安全方法2执行");
                }
            }
        }
    }
    
    // 实践3:使用tryLock避免无限等待
    public static class TimeoutLocking {
        private final ReentrantLock lock = new ReentrantLock();
        private final List<String> data = new ArrayList<>();
        
        public boolean addWithTimeout(String item, long timeout, TimeUnit unit) {
            try {
                if (lock.tryLock(timeout, unit)) {
                    try {
                        data.add(item);
                        System.out.println("成功添加: " + item);
                        return true;
                    } finally {
                        lock.unlock();
                    }
                } else {
                    System.out.println("获取锁超时,放弃添加: " + item);
                    return false;
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
        
        public void simulateContention() {
            // 模拟锁竞争
            Thread holder = new Thread(() -> {
                lock.lock();
                try {
                    System.out.println("长时间持有锁...");
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                } finally {
                    lock.unlock();
                    System.out.println("释放锁");
                }
            });
            
            Thread waiter = new Thread(() -> {
                try {
                    Thread.sleep(100); // 确保holder先获得锁
                    addWithTimeout("测试项", 1, TimeUnit.SECONDS);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            });
            
            holder.start();
            waiter.start();
            
            try {
                holder.join();
                waiter.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    public static void main(String[] args) {
        System.out.println("=== 锁范围优化演示 ===");
        OptimizedCounter counter = new OptimizedCounter();
        
        long start = System.currentTimeMillis();
        Thread[] threads = new Thread[5];
        for (int i = 0; i < threads.length; i++) {
            threads[i] = new Thread(() -> {
                for (int j = 0; j < 3; j++) {
                    counter.goodIncrement();
                }
            });
            threads[i].start();
        }
        
        for (Thread thread : threads) {
            try {
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        
        long end = System.currentTimeMillis();
        System.out.println("最终计数: " + counter.getCount() + ", 耗时: " + (end - start) + "ms");
        
        System.out.println("\n=== 死锁避免演示 ===");
        DeadlockAvoidance avoidance = new DeadlockAvoidance();
        avoidance.safeMethod1();
        avoidance.safeMethod2();
        
        System.out.println("\n=== 超时锁演示 ===");
        TimeoutLocking timeoutLocking = new TimeoutLocking();
        timeoutLocking.simulateContention();
    }
}

# 3. 线程池最佳实践

# 3.1 线程池配置和使用

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

public class ThreadPoolBestPractices {
    
    // 实践1:合理配置线程池参数
    public static class ThreadPoolFactory {
        
        // CPU密集型任务的线程池
        public static ThreadPoolExecutor createCpuIntensivePool() {
            int corePoolSize = Runtime.getRuntime().availableProcessors();
            int maximumPoolSize = corePoolSize;
            long keepAliveTime = 0L;
            
            return new ThreadPoolExecutor(
                corePoolSize,
                maximumPoolSize,
                keepAliveTime,
                TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<>(100),
                new CustomThreadFactory("CPU-Worker"),
                new ThreadPoolExecutor.CallerRunsPolicy()
            );
        }
        
        // IO密集型任务的线程池
        public static ThreadPoolExecutor createIoIntensivePool() {
            int corePoolSize = Runtime.getRuntime().availableProcessors() * 2;
            int maximumPoolSize = corePoolSize * 2;
            long keepAliveTime = 60L;
            
            return new ThreadPoolExecutor(
                corePoolSize,
                maximumPoolSize,
                keepAliveTime,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(200),
                new CustomThreadFactory("IO-Worker"),
                new ThreadPoolExecutor.CallerRunsPolicy()
            );
        }
        
        // 自定义线程工厂
        static class CustomThreadFactory implements ThreadFactory {
            private final AtomicInteger threadNumber = new AtomicInteger(1);
            private final String namePrefix;
            
            CustomThreadFactory(String namePrefix) {
                this.namePrefix = namePrefix;
            }
            
            @Override
            public Thread newThread(Runnable r) {
                Thread t = new Thread(r, namePrefix + "-" + threadNumber.getAndIncrement());
                t.setDaemon(false);
                t.setPriority(Thread.NORM_PRIORITY);
                
                // 设置异常处理器
                t.setUncaughtExceptionHandler((thread, ex) -> {
                    System.err.println("线程 " + thread.getName() + " 发生异常: " + ex.getMessage());
                    ex.printStackTrace();
                });
                
                return t;
            }
        }
    }
    
    // 实践2:正确处理任务异常
    public static class TaskExceptionHandling {
        
        public static void demonstrateExceptionHandling() {
            ThreadPoolExecutor executor = ThreadPoolFactory.createCpuIntensivePool();
            
            // 方法1:使用Future捕获异常
            Future<?> future = executor.submit(() -> {
                if (Math.random() > 0.5) {
                    throw new RuntimeException("模拟任务异常");
                }
                System.out.println("任务正常完成");
            });
            
            try {
                future.get(5, TimeUnit.SECONDS);
                System.out.println("任务成功完成");
            } catch (ExecutionException e) {
                System.err.println("任务执行异常: " + e.getCause().getMessage());
            } catch (TimeoutException e) {
                System.err.println("任务执行超时");
                future.cancel(true);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            
            // 方法2:在任务内部处理异常
            executor.submit(() -> {
                try {
                    // 可能抛出异常的代码
                    if (Math.random() > 0.5) {
                        throw new RuntimeException("内部异常");
                    }
                    System.out.println("内部异常处理:任务正常完成");
                } catch (Exception e) {
                    System.err.println("内部异常处理:捕获到异常 - " + e.getMessage());
                    // 记录日志、发送告警等
                }
            });
            
            // 优雅关闭
            executor.shutdown();
            try {
                if (!executor.awaitTermination(5, TimeUnit.SECONDS)) {
                    executor.shutdownNow();
                }
            } catch (InterruptedException e) {
                executor.shutdownNow();
                Thread.currentThread().interrupt();
            }
        }
    }
    
    // 实践3:监控线程池状态
    public static class ThreadPoolMonitoring {
        
        public static void monitorThreadPool() {
            ThreadPoolExecutor executor = ThreadPoolFactory.createIoIntensivePool();
            
            // 启动监控线程
            ScheduledExecutorService monitor = Executors.newSingleThreadScheduledExecutor();
            monitor.scheduleAtFixedRate(() -> {
                System.out.println("=== 线程池状态 ===");
                System.out.println("核心线程数: " + executor.getCorePoolSize());
                System.out.println("当前线程数: " + executor.getPoolSize());
                System.out.println("活跃线程数: " + executor.getActiveCount());
                System.out.println("队列大小: " + executor.getQueue().size());
                System.out.println("已完成任务数: " + executor.getCompletedTaskCount());
                System.out.println("总任务数: " + executor.getTaskCount());
                System.out.println();
            }, 0, 1, TimeUnit.SECONDS);
            
            // 提交一些任务
            for (int i = 0; i < 20; i++) {
                final int taskId = i;
                executor.submit(() -> {
                    try {
                        System.out.println("执行任务 " + taskId);
                        Thread.sleep(2000); // 模拟IO操作
                        System.out.println("完成任务 " + taskId);
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                });
            }
            
            // 运行5秒后关闭
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            
            monitor.shutdown();
            executor.shutdown();
            
            try {
                executor.awaitTermination(10, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    public static void main(String[] args) {
        System.out.println("=== 异常处理演示 ===");
        TaskExceptionHandling.demonstrateExceptionHandling();
        
        System.out.println("\n=== 线程池监控演示 ===");
        ThreadPoolMonitoring.monitorThreadPool();
    }
}

# 4. 性能优化策略

# 4.1 减少锁竞争

import java.util.concurrent.atomic.*;
import java.util.concurrent.locks.StampedLock;
import java.util.*;

public class PerformanceOptimization {
    
    // 策略1:使用原子类替代锁
    public static class AtomicVsSynchronized {
        private int synchronizedCounter = 0;
        private final AtomicInteger atomicCounter = new AtomicInteger(0);
        private final Object lock = new Object();
        
        public void synchronizedIncrement() {
            synchronized (lock) {
                synchronizedCounter++;
            }
        }
        
        public void atomicIncrement() {
            atomicCounter.incrementAndGet();
        }
        
        public void performanceTest() {
            int threadCount = 10;
            int incrementsPerThread = 100000;
            
            // 测试synchronized
            long start = System.currentTimeMillis();
            Thread[] threads = new Thread[threadCount];
            
            for (int i = 0; i < threadCount; i++) {
                threads[i] = new Thread(() -> {
                    for (int j = 0; j < incrementsPerThread; j++) {
                        synchronizedIncrement();
                    }
                });
            }
            
            for (Thread thread : threads) {
                thread.start();
            }
            
            for (Thread thread : threads) {
                try {
                    thread.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            
            long synchronizedTime = System.currentTimeMillis() - start;
            
            // 测试atomic
            start = System.currentTimeMillis();
            
            for (int i = 0; i < threadCount; i++) {
                threads[i] = new Thread(() -> {
                    for (int j = 0; j < incrementsPerThread; j++) {
                        atomicIncrement();
                    }
                });
            }
            
            for (Thread thread : threads) {
                thread.start();
            }
            
            for (Thread thread : threads) {
                try {
                    thread.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            
            long atomicTime = System.currentTimeMillis() - start;
            
            System.out.println("Synchronized计数器: " + synchronizedCounter + 
                             ", 耗时: " + synchronizedTime + "ms");
            System.out.println("Atomic计数器: " + atomicCounter.get() + 
                             ", 耗时: " + atomicTime + "ms");
            System.out.println("性能提升: " + (synchronizedTime * 100.0 / atomicTime - 100) + "%");
        }
    }
    
    // 策略2:读写分离锁
    public static class ReadWriteLockOptimization {
        private final StampedLock stampedLock = new StampedLock();
        private final Map<String, String> data = new HashMap<>();
        
        // 乐观读
        public String optimisticRead(String key) {
            long stamp = stampedLock.tryOptimisticRead();
            String value = data.get(key);
            
            if (!stampedLock.validate(stamp)) {
                // 乐观读失败,升级为悲观读锁
                stamp = stampedLock.readLock();
                try {
                    value = data.get(key);
                } finally {
                    stampedLock.unlockRead(stamp);
                }
            }
            
            return value;
        }
        
        // 写操作
        public void write(String key, String value) {
            long stamp = stampedLock.writeLock();
            try {
                data.put(key, value);
            } finally {
                stampedLock.unlockWrite(stamp);
            }
        }
        
        public void demonstrateReadWritePerformance() {
            // 预填充数据
            for (int i = 0; i < 1000; i++) {
                write("key" + i, "value" + i);
            }
            
            int readerCount = 8;
            int writerCount = 2;
            int operationsPerThread = 10000;
            
            Thread[] readers = new Thread[readerCount];
            Thread[] writers = new Thread[writerCount];
            
            long start = System.currentTimeMillis();
            
            // 启动读线程
            for (int i = 0; i < readerCount; i++) {
                readers[i] = new Thread(() -> {
                    for (int j = 0; j < operationsPerThread; j++) {
                        String key = "key" + (j % 1000);
                        optimisticRead(key);
                    }
                });
                readers[i].start();
            }
            
            // 启动写线程
            for (int i = 0; i < writerCount; i++) {
                final int writerId = i;
                writers[i] = new Thread(() -> {
                    for (int j = 0; j < operationsPerThread / 10; j++) {
                        String key = "key" + (j % 1000);
                        write(key, "newValue" + writerId + "-" + j);
                    }
                });
                writers[i].start();
            }
            
            // 等待所有线程完成
            for (Thread reader : readers) {
                try {
                    reader.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            
            for (Thread writer : writers) {
                try {
                    writer.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            
            long end = System.currentTimeMillis();
            System.out.println("读写分离锁测试完成,耗时: " + (end - start) + "ms");
        }
    }
    
    // 策略3:减少上下文切换
    public static class ContextSwitchOptimization {
        
        public static void demonstrateContextSwitchImpact() {
            int taskCount = 1000;
            
            // 方案1:每个任务一个线程(大量上下文切换)
            long start = System.currentTimeMillis();
            Thread[] threads = new Thread[taskCount];
            
            for (int i = 0; i < taskCount; i++) {
                threads[i] = new Thread(() -> {
                    // 简单计算任务
                    int sum = 0;
                    for (int j = 0; j < 1000; j++) {
                        sum += j;
                    }
                });
                threads[i].start();
            }
            
            for (Thread thread : threads) {
                try {
                    thread.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            
            long manyThreadsTime = System.currentTimeMillis() - start;
            
            // 方案2:使用线程池(减少上下文切换)
            start = System.currentTimeMillis();
            ExecutorService executor = Executors.newFixedThreadPool(
                Runtime.getRuntime().availableProcessors());
            
            CountDownLatch latch = new CountDownLatch(taskCount);
            
            for (int i = 0; i < taskCount; i++) {
                executor.submit(() -> {
                    try {
                        // 相同的计算任务
                        int sum = 0;
                        for (int j = 0; j < 1000; j++) {
                            sum += j;
                        }
                    } finally {
                        latch.countDown();
                    }
                });
            }
            
            try {
                latch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            
            executor.shutdown();
            long threadPoolTime = System.currentTimeMillis() - start;
            
            System.out.println("大量线程方案耗时: " + manyThreadsTime + "ms");
            System.out.println("线程池方案耗时: " + threadPoolTime + "ms");
            System.out.println("性能提升: " + (manyThreadsTime * 100.0 / threadPoolTime - 100) + "%");
        }
    }
    
    public static void main(String[] args) {
        System.out.println("=== 原子类vs同步块性能测试 ===");
        AtomicVsSynchronized atomicTest = new AtomicVsSynchronized();
        atomicTest.performanceTest();
        
        System.out.println("\n=== 读写分离锁性能测试 ===");
        ReadWriteLockOptimization rwTest = new ReadWriteLockOptimization();
        rwTest.demonstrateReadWritePerformance();
        
        System.out.println("\n=== 上下文切换优化测试 ===");
        ContextSwitchOptimization.demonstrateContextSwitchImpact();
    }
}

# 5. 常见陷阱和解决方案

# 5.1 并发编程常见问题

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

public class ConcurrencyPitfalls {
    
    // 陷阱1:竞态条件
    public static class RaceConditionExample {
        private int counter = 0;
        private final AtomicBoolean flag = new AtomicBoolean(false);
        
        // 错误:存在竞态条件
        public void unsafeIncrement() {
            if (counter < 1000) { // 检查
                counter++; // 操作(非原子)
            }
        }
        
        // 正确:使用同步
        public synchronized void safeIncrement() {
            if (counter < 1000) {
                counter++;
            }
        }
        
        public void demonstrateRaceCondition() {
            System.out.println("=== 竞态条件演示 ===");
            
            // 重置计数器
            counter = 0;
            
            Thread[] threads = new Thread[10];
            for (int i = 0; i < threads.length; i++) {
                threads[i] = new Thread(() -> {
                    for (int j = 0; j < 200; j++) {
                        unsafeIncrement();
                    }
                });
            }
            
            for (Thread thread : threads) {
                thread.start();
            }
            
            for (Thread thread : threads) {
                try {
                    thread.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            
            System.out.println("不安全递增结果: " + counter + " (期望: 1000)");
            
            // 测试安全版本
            counter = 0;
            
            for (int i = 0; i < threads.length; i++) {
                threads[i] = new Thread(() -> {
                    for (int j = 0; j < 200; j++) {
                        safeIncrement();
                    }
                });
            }
            
            for (Thread thread : threads) {
                thread.start();
            }
            
            for (Thread thread : threads) {
                try {
                    thread.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            
            System.out.println("安全递增结果: " + counter + " (期望: 1000)");
        }
    }
    
    // 陷阱2:内存可见性问题
    public static class VisibilityProblem {
        private boolean stopFlag = false;
        private volatile boolean volatileStopFlag = false;
        
        public void demonstrateVisibilityIssue() {
            System.out.println("\n=== 内存可见性问题演示 ===");
            
            // 可能无法停止的线程(可见性问题)
            Thread problematicThread = new Thread(() -> {
                int count = 0;
                while (!stopFlag) {
                    count++;
                    if (count % 100000000 == 0) {
                        System.out.println("问题线程仍在运行... count = " + count);
                    }
                }
                System.out.println("问题线程停止,count = " + count);
            });
            
            // 能够正常停止的线程(使用volatile)
            Thread correctThread = new Thread(() -> {
                int count = 0;
                while (!volatileStopFlag) {
                    count++;
                    if (count % 100000000 == 0) {
                        System.out.println("正确线程运行中... count = " + count);
                    }
                }
                System.out.println("正确线程停止,count = " + count);
            });
            
            problematicThread.start();
            correctThread.start();
            
            try {
                Thread.sleep(1000);
                System.out.println("设置停止标志...");
                stopFlag = true;
                volatileStopFlag = true;
                
                // 等待线程结束
                correctThread.join(2000);
                
                if (problematicThread.isAlive()) {
                    System.out.println("问题线程由于可见性问题未能停止,强制中断");
                    problematicThread.interrupt();
                }
                
                problematicThread.join(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    // 陷阱3:死锁
    public static class DeadlockExample {
        private final Object lock1 = new Object();
        private final Object lock2 = new Object();
        
        public void method1() {
            synchronized (lock1) {
                System.out.println(Thread.currentThread().getName() + ": 获得lock1");
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                
                synchronized (lock2) {
                    System.out.println(Thread.currentThread().getName() + ": 获得lock2");
                }
            }
        }
        
        public void method2() {
            synchronized (lock2) {
                System.out.println(Thread.currentThread().getName() + ": 获得lock2");
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                
                synchronized (lock1) {
                    System.out.println(Thread.currentThread().getName() + ": 获得lock1");
                }
            }
        }
        
        public void demonstrateDeadlock() {
            System.out.println("\n=== 死锁演示(注意:可能导致程序挂起) ===");
            
            Thread thread1 = new Thread(() -> {
                method1();
            }, "Thread-1");
            
            Thread thread2 = new Thread(() -> {
                method2();
            }, "Thread-2");
            
            thread1.start();
            thread2.start();
            
            try {
                // 等待一段时间,如果线程未结束则可能发生死锁
                thread1.join(3000);
                thread2.join(3000);
                
                if (thread1.isAlive() || thread2.isAlive()) {
                    System.out.println("检测到可能的死锁,中断线程");
                    thread1.interrupt();
                    thread2.interrupt();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    // 陷阱4:资源泄露
    public static class ResourceLeakExample {
        
        // 错误:未正确关闭线程池
        public void badResourceManagement() {
            ExecutorService executor = Executors.newFixedThreadPool(5);
            
            for (int i = 0; i < 10; i++) {
                executor.submit(() -> {
                    System.out.println("执行任务: " + Thread.currentThread().getName());
                });
            }
            
            // 错误:忘记关闭线程池,导致资源泄露
            // executor.shutdown();
        }
        
        // 正确:使用try-with-resources或finally确保资源释放
        public void goodResourceManagement() {
            ExecutorService executor = Executors.newFixedThreadPool(5);
            
            try {
                for (int i = 0; i < 10; i++) {
                    executor.submit(() -> {
                        System.out.println("执行任务: " + Thread.currentThread().getName());
                    });
                }
            } finally {
                executor.shutdown();
                try {
                    if (!executor.awaitTermination(5, TimeUnit.SECONDS)) {
                        executor.shutdownNow();
                    }
                } catch (InterruptedException e) {
                    executor.shutdownNow();
                    Thread.currentThread().interrupt();
                }
            }
        }
        
        public void demonstrateResourceManagement() {
            System.out.println("\n=== 资源管理演示 ===");
            System.out.println("正确的资源管理:");
            goodResourceManagement();
        }
    }
    
    public static void main(String[] args) {
        RaceConditionExample raceExample = new RaceConditionExample();
        raceExample.demonstrateRaceCondition();
        
        VisibilityProblem visibilityExample = new VisibilityProblem();
        visibilityExample.demonstrateVisibilityIssue();
        
        // 注意:死锁演示可能导致程序挂起
        // DeadlockExample deadlockExample = new DeadlockExample();
        // deadlockExample.demonstrateDeadlock();
        
        ResourceLeakExample resourceExample = new ResourceLeakExample();
        resourceExample.demonstrateResourceManagement();
    }
}

# 6. 总结

# 6.1 核心原则总结

  1. 安全性第一:确保程序的正确性,避免数据竞争和不一致状态
  2. 性能其次:在保证安全的前提下优化性能
  3. 简单性:优先选择简单、易理解的解决方案
  4. 可维护性:编写清晰、可读的并发代码

# 6.2 最佳实践清单

# 设计阶段

  • [ ] 最小化共享状态
  • [ ] 优先使用不可变对象
  • [ ] 合理划分线程职责
  • [ ] 选择合适的并发工具

# 实现阶段

  • [ ] 正确使用同步机制
  • [ ] 避免锁嵌套和死锁
  • [ ] 处理中断和异常
  • [ ] 确保资源正确释放

# 测试阶段

  • [ ] 进行并发测试
  • [ ] 压力测试和性能测试
  • [ ] 死锁检测
  • [ ] 内存泄露检查

# 监控阶段

  • [ ] 监控线程池状态
  • [ ] 跟踪性能指标
  • [ ] 日志记录和异常处理
  • [ ] 定期性能调优

# 6.3 工具推荐

  1. 并发工具类

    • java.util.concurrent包下的工具
    • AtomicXxx原子类
    • ConcurrentHashMap等并发集合
  2. 测试工具

    • JUnit并发测试
    • JMH性能基准测试
    • VisualVM性能分析
  3. 监控工具

    • JConsole
    • JProfiler
    • Arthas

通过遵循这些最佳实践,可以编写出安全、高效、可维护的并发程序。记住,并发编程是一个复杂的领域,需要不断学习和实践来掌握。