Java并发编程实战:线程池与并发工具类

Java并发编程实战:线程池与并发工具类

一、线程池原理与最佳实践

线程池是Java并发编程的核心组件,合理使用线程池可以显著提升系统性能。

1.1 线程池核心参数

java 复制代码
ThreadPoolExecutor executor = new ThreadPoolExecutor(
    4,                              // corePoolSize: 核心线程数
    8,                              // maximumPoolSize: 最大线程数
    60L,                            // keepAliveTime: 空闲线程存活时间
    TimeUnit.SECONDS,               // unit: 时间单位
    new ArrayBlockingQueue<>(100),  // workQueue: 任务队列
    Executors.defaultThreadFactory(),// threadFactory: 线程工厂
    new CallerRunsPolicy()          // handler: 拒绝策略
);

1.2 拒绝策略选择

策略 行为 适用场景
CallerRunsPolicy 调用者线程执行 不重要的后台任务
AbortPolicy 抛出异常 需要快速失败的场景
DiscardPolicy 静默丢弃 日志收集等非关键任务
DiscardOldestPolicy 丢弃最老任务 实时性要求高的场景

1.3 线程池监控

java 复制代码
public class ThreadPoolMonitor {
    
    public static void monitor(ThreadPoolExecutor executor) {
        ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
        scheduler.scheduleAtFixedRate(() -> {
            System.out.printf(
                "线程池状态: 活跃=%d, 队列=%d, 完成=%d, 池大小=%d%n",
                executor.getActiveCount(),
                executor.getQueue().size(),
                executor.getCompletedTaskCount(),
                executor.getPoolSize()
            );
        }, 0, 10, TimeUnit.SECONDS);
    }
}

二、并发工具类深度解析

2.1 CountDownLatch 同步屏障

java 复制代码
public class DataLoader {
    
    private final CountDownLatch latch;
    private List<DataResult> results;
    
    public void loadData(List<String> sources) throws InterruptedException {
        latch = new CountDownLatch(sources.size());
        results = Collections.synchronizedList(new ArrayList<>());
        
        ExecutorService executor = Executors.newFixedThreadPool(4);
        for (String source : sources) {
            executor.submit(() -> {
                try {
                    DataResult result = fetchData(source);
                    results.add(result);
                } finally {
                    latch.countDown();
                }
            });
        }
        
        latch.await(5, TimeUnit.MINUTES);
        executor.shutdown();
    }
}

2.2 CyclicBarrier 循环屏障

java 复制代码
public class DataProcessor {
    
    private final CyclicBarrier barrier;
    
    public DataProcessor(int workerCount) {
        this.barrier = new CyclicBarrier(workerCount, () -> {
            System.out.println("所有阶段任务完成,进入下一阶段");
        });
    }
    
    public void process(List<DataChunk> chunks) throws Exception {
        ExecutorService executor = Executors.newFixedThreadPool(barrier.getParties());
        
        for (DataChunk chunk : chunks) {
            executor.submit(() -> {
                try {
                    processChunk(chunk);
                    barrier.await();
                    mergeResults();
                    barrier.await();
                } catch (Exception e) {
                    barrier.reset();
                }
            });
        }
    }
}

2.3 Semaphore 信号量控制

java 复制代码
public class ResourcePool {
    
    private final Semaphore semaphore;
    private final List<Resource> resources;
    
    public ResourcePool(int size) {
        this.semaphore = new Semaphore(size);
        this.resources = new ArrayList<>();
        for (int i = 0; i < size; i++) {
            resources.add(new Resource(i));
        }
    }
    
    public Resource acquire() throws InterruptedException {
        semaphore.acquire();
        return resources.remove(0);
    }
    
    public void release(Resource resource) {
        resources.add(resource);
        semaphore.release();
    }
}

2.4 Phaser 阶段同步器

java 复制代码
public class MultiPhaseTask {
    
    private final Phaser phaser;
    
    public MultiPhaseTask(int parties) {
        this.phaser = new Phaser(parties) {
            @Override
            protected boolean onAdvance(int phase, int registeredParties) {
                System.out.printf("阶段 %d 完成,参与方: %d%n", phase, registeredParties);
                return phase >= 3;
            }
        };
    }
    
    public void execute() {
        for (int i = 0; i < 4; i++) {
            new Thread(() -> {
                doPhase1();
                phaser.arriveAndAwaitAdvance();
                
                doPhase2();
                phaser.arriveAndAwaitAdvance();
                
                doPhase3();
                phaser.arriveAndDeregister();
            }).start();
        }
    }
}

三、原子类操作

3.1 AtomicReference 原子引用

java 复制代码
public class NonBlockingCache<K, V> {
    
    private static class Node<K, V> {
        final K key;
        volatile V value;
        volatile Node<K, V> next;
        
        Node(K key, V value) {
            this.key = key;
            this.value = value;
        }
    }
    
    private final AtomicReference<Node<K, V>> head = new AtomicReference<>();
    
    public V get(K key) {
        Node<K, V> current = head.get();
        while (current != null) {
            if (key.equals(current.key)) {
                return current.value;
            }
            current = current.next;
        }
        return null;
    }
    
    public void put(K key, V value) {
        Node<K, V> newNode = new Node<>(key, value);
        while (!head.compareAndSet(head.get(), newNode)) {
            newNode.next = head.get();
        }
    }
}

3.2 LongAdder 高性能计数器

java 复制代码
public class PerformanceCounter {
    
    private final LongAdder counter = new LongAdder();
    private final LongAdder totalTime = new LongAdder();
    
    public void record(long duration) {
        counter.increment();
        totalTime.add(duration);
    }
    
    public double getAverage() {
        long count = counter.sum();
        return count > 0 ? (double) totalTime.sum() / count : 0;
    }
}

四、并发容器使用技巧

4.1 ConcurrentHashMap 分段锁机制

java 复制代码
public class ConcurrentCache {
    
    private final ConcurrentHashMap<String, CacheEntry> cache = new ConcurrentHashMap<>();
    
    public Object get(String key) {
        CacheEntry entry = cache.get(key);
        if (entry == null) {
            return null;
        }
        if (entry.isExpired()) {
            cache.remove(key, entry);
            return null;
        }
        return entry.getValue();
    }
    
    public void put(String key, Object value, long ttl) {
        cache.put(key, new CacheEntry(value, ttl));
    }
}

4.2 CopyOnWriteArrayList 读写分离

java 复制代码
public class EventListenerManager {
    
    private final CopyOnWriteArrayList<EventListener> listeners = new CopyOnWriteArrayList<>();
    
    public void register(EventListener listener) {
        listeners.addIfAbsent(listener);
    }
    
    public void unregister(EventListener listener) {
        listeners.remove(listener);
    }
    
    public void fireEvent(Event event) {
        for (EventListener listener : listeners) {
            listener.onEvent(event);
        }
    }
}

五、CompletableFuture 异步编程

5.1 链式调用

java 复制代码
public class AsyncService {
    
    public CompletableFuture<User> getUserById(Long id) {
        return CompletableFuture.supplyAsync(() -> userRepository.findById(id))
            .thenApply(user -> {
                if (user.isPresent()) {
                    return user.get();
                }
                throw new UserNotFoundException("User not found: " + id);
            });
    }
    
    public CompletableFuture<List<Order>> getOrdersByUserId(Long userId) {
        return CompletableFuture.supplyAsync(() -> orderRepository.findByUserId(userId));
    }
    
    public CompletableFuture<UserProfile> getUserProfile(Long userId) {
        CompletableFuture<User> userFuture = getUserById(userId);
        CompletableFuture<List<Order>> ordersFuture = getOrdersByUserId(userId);
        
        return CompletableFuture.allOf(userFuture, ordersFuture)
            .thenApply(v -> {
                User user = userFuture.join();
                List<Order> orders = ordersFuture.join();
                return UserProfile.builder()
                    .user(user)
                    .orders(orders)
                    .build();
            });
    }
}

5.2 异常处理

java 复制代码
public CompletableFuture<Result> processWithFallback() {
    return CompletableFuture.supplyAsync(this::doRiskyOperation)
        .exceptionally(ex -> {
            log.error("操作失败: {}", ex.getMessage());
            return Result.failure("降级处理");
        })
        .thenApply(result -> {
            if (result.isSuccess()) {
                return enhanceResult(result);
            }
            return result;
        });
}

六、并发编程常见问题

6.1 线程安全问题

java 复制代码
// 错误示例
public class UnsafeCounter {
    private int count = 0;
    
    public void increment() {
        count++;  // 非原子操作
    }
}

// 正确示例
public class SafeCounter {
    private final AtomicInteger count = new AtomicInteger(0);
    
    public void increment() {
        count.incrementAndGet();
    }
}

6.2 死锁问题

java 复制代码
// 死锁示例
public class DeadlockExample {
    private final Object lock1 = new Object();
    private final Object lock2 = new Object();
    
    public void method1() {
        synchronized (lock1) {
            synchronized (lock2) {
                // 业务逻辑
            }
        }
    }
    
    public void method2() {
        synchronized (lock2) {  // 锁顺序不一致
            synchronized (lock1) {
                // 业务逻辑
            }
        }
    }
}

6.3 资源泄漏

java 复制代码
// 错误示例 - 忘记关闭资源
ExecutorService executor = Executors.newFixedThreadPool(4);
executor.submit(() -> processData());

// 正确示例
ExecutorService executor = Executors.newFixedThreadPool(4);
try {
    executor.submit(() -> processData());
} finally {
    executor.shutdown();
    executor.awaitTermination(1, TimeUnit.MINUTES);
}

七、性能优化建议

7.1 线程池大小计算公式

复制代码
线程池大小 = CPU核心数 × (1 + I/O耗时 / CPU耗时)

7.2 避免线程饥饿

java 复制代码
// 使用不同的线程池处理不同类型的任务
ExecutorService cpuExecutor = Executors.newFixedThreadPool(4);
ExecutorService ioExecutor = Executors.newFixedThreadPool(16);
ExecutorService priorityExecutor = Executors.newFixedThreadPool(2);

7.3 使用 ThreadLocal 减少锁竞争

java 复制代码
public class RequestContext {
    
    private static final ThreadLocal<RequestInfo> context = ThreadLocal.withInitial(RequestInfo::new);
    
    public static RequestInfo get() {
        return context.get();
    }
    
    public static void set(RequestInfo info) {
        context.set(info);
    }
    
    public static void clear() {
        context.remove();
    }
}

八、总结

Java并发编程需要掌握以下核心要点:

  1. 线程池:合理配置参数,选择合适的拒绝策略
  2. 同步工具:根据场景选择CountDownLatch、CyclicBarrier等
  3. 原子操作:使用原子类保证线程安全
  4. 并发容器:选择适合的并发数据结构
  5. 异步编程:使用CompletableFuture简化异步流程
  6. 问题排查:警惕死锁、资源泄漏等常见问题

通过系统化学习和实践,可以构建高效、稳定的并发系统。

相关推荐
折哥的程序人生 · 物流技术专研9 小时前
Java面试85题图解版 · 特别篇:2026后端高频面试题复盘(算法底层逻辑+高并发架构设计全解析,附Java实战代码)
java·网络·数据库·算法·面试
一条泥憨鱼9 小时前
【Redis】数据类型和常用命令
java·数据库·redis·后端·缓存
云烟成雨TD9 小时前
Spring AI Alibaba 1.x 系列【78】沙箱(Sandbox)
java·人工智能·spring
程序员二叉9 小时前
【Java】 异常高频面试题精讲 | 易错点+对比总结
java·开发语言·面试
周航宇JoeZhou10 小时前
JB3-9-SpringAI(二)
java·ai·agent·多智能体·调度·智能体·观察
好家伙VCC10 小时前
Web Components主题热切换方案揭秘
java·前端
慕木沐10 小时前
Google ADK Java 1.0版本 核心机制与实战 Demo
java·开发语言·python
焦虑的说说11 小时前
秒杀系统设计方案
java
许彰午11 小时前
30_Java Stream流操作全解
java·windows·python
qq_25183645711 小时前
基于java Web网络订餐系统设计与实现 源码文档
java·开发语言·前端