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. 问题排查:警惕死锁、资源泄漏等常见问题

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

相关推荐
devilnumber3 小时前
JDK6→JDK7→JDK8 重点技术更新(精简背诵版)
java
云烟成雨TD3 小时前
Spring AI Alibaba 1.x 系列【61】Graph 持久化执行
java·人工智能·spring
muqsen3 小时前
Java 分布式相关面试题总结
java·开发语言·分布式
做个文艺程序员3 小时前
第02篇:搭建 ES 集群 + Spring Boot 整合实战——从 Docker Compose 到 Java 客户端全覆盖
java·spring boot·elasticsearch
Jinkxs3 小时前
LoadBalancer- 简单限流策略:Nginx 基于连接 / 请求的限流实现
java·运维·nginx
fenglllle3 小时前
JDK8升级JDK17使用CompletableFuture在线程中classloader的变化
java·开发语言·jvm
计算机安禾3 小时前
【c++面向对象编程】第44篇:typename与class的区别,依赖类型名与template消除歧义
java·jvm·c++
JAVA面经实录9173 小时前
Java+SpringAI企业级实战项目完整官方文档(生产终版)
java·开发语言·spring·ai编程
梵得儿SHI3 小时前
Java IO 流进阶:Buffer 与 Channel 核心概念解析及与传统 IO 的本质区别
java·开发语言·高并发·nio·channel·buffer·提升io效率