程序员鸭梨头像

Java 并发编程模式:构建高效的并发系统

Java 并发编程模式:构建高效的并发系统

一、引言

在现代软件开发中,并发编程已经成为必备技能。Java 提供了丰富的并发工具和 API,帮助开发者构建高效、可靠的并发系统。掌握并发编程模式能够帮助我们更好地利用多核处理器的性能,提升应用的吞吐量和响应速度。

本文将深入探讨 Java 中常用的并发编程模式,包括线程池、生产者-消费者、读写锁、信号量、屏障等,并结合实际案例展示如何在项目中应用这些模式。

二、线程池模式

2.1 线程池基础

public class ThreadPoolExample {
    
    private static final ExecutorService executor = Executors.newFixedThreadPool(10);
    
    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            final int taskId = i;
            executor.submit(() -> {
                System.out.println("Task " + taskId + " executed by " + 
                    Thread.currentThread().getName());
            });
        }
        executor.shutdown();
    }
}

2.2 自定义线程池配置

@Configuration
public class ThreadPoolConfig {
    
    @Bean("taskExecutor")
    public ExecutorService taskExecutor() {
        ThreadFactory threadFactory = new ThreadFactory() {
            private final AtomicInteger counter = new AtomicInteger(0);
            
            @Override
            public Thread newThread(Runnable r) {
                Thread thread = new Thread(r);
                thread.setName("task-executor-" + counter.incrementAndGet());
                thread.setDaemon(false);
                return thread;
            }
        };
        
        return new ThreadPoolExecutor(
            10,              // corePoolSize
            20,              // maximumPoolSize
            60L,             // keepAliveTime
            TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(100),
            threadFactory,
            new ThreadPoolExecutor.CallerRunsPolicy()
        );
    }
}

2.3 线程池监控

public class ThreadPoolMonitor {
    
    private final ThreadPoolExecutor executor;
    
    public ThreadPoolMonitor(ThreadPoolExecutor executor) {
        this.executor = executor;
    }
    
    public Map<String, Object> getPoolStats() {
        Map<String, Object> stats = new HashMap<>();
        stats.put("poolSize", executor.getPoolSize());
        stats.put("activeCount", executor.getActiveCount());
        stats.put("queueSize", executor.getQueue().size());
        stats.put("completedTaskCount", executor.getCompletedTaskCount());
        stats.put("largestPoolSize", executor.getLargestPoolSize());
        return stats;
    }
}

三、生产者-消费者模式

3.1 使用 BlockingQueue

public class ProducerConsumerPattern {
    
    private static final BlockingQueue<String> queue = new ArrayBlockingQueue<>(10);
    
    static class Producer implements Runnable {
        @Override
        public void run() {
            try {
                for (int i = 0; i < 20; i++) {
                    String message = "Message " + i;
                    queue.put(message);
                    System.out.println("Produced: " + message);
                    Thread.sleep(100);
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }
    
    static class Consumer implements Runnable {
        @Override
        public void run() {
            try {
                while (!Thread.currentThread().isInterrupted()) {
                    String message = queue.take();
                    System.out.println("Consumed: " + message);
                    Thread.sleep(200);
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }
    
    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(3);
        executor.submit(new Producer());
        executor.submit(new Consumer());
        executor.submit(new Consumer());
        executor.shutdown();
    }
}

3.2 带信号量的生产者-消费者

public class BoundedProducerConsumer {
    
    private final Semaphore emptySlots;
    private final Semaphore filledSlots;
    private final Object[] buffer;
    private int putIndex, takeIndex;
    
    public BoundedProducerConsumer(int capacity) {
        this.buffer = new Object[capacity];
        this.emptySlots = new Semaphore(capacity);
        this.filledSlots = new Semaphore(0);
        this.putIndex = 0;
        this.takeIndex = 0;
    }
    
    public void put(Object item) throws InterruptedException {
        emptySlots.acquire();
        synchronized (this) {
            buffer[putIndex] = item;
            putIndex = (putIndex + 1) % buffer.length;
        }
        filledSlots.release();
    }
    
    public Object take() throws InterruptedException {
        filledSlots.acquire();
        Object item;
        synchronized (this) {
            item = buffer[takeIndex];
            takeIndex = (takeIndex + 1) % buffer.length;
        }
        emptySlots.release();
        return item;
    }
}

四、读写锁模式

4.1 ReadWriteLock 使用

public class Cache<K, V> {
    
    private final Map<K, V> cache = new HashMap<>();
    private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
    
    public V get(K key) {
        rwLock.readLock().lock();
        try {
            return cache.get(key);
        } finally {
            rwLock.readLock().unlock();
        }
    }
    
    public void put(K key, V value) {
        rwLock.writeLock().lock();
        try {
            cache.put(key, value);
        } finally {
            rwLock.writeLock().unlock();
        }
    }
    
    public void remove(K key) {
        rwLock.writeLock().lock();
        try {
            cache.remove(key);
        } finally {
            rwLock.writeLock().unlock();
        }
    }
}

4.2 读写锁优化

public class OptimizedCache<K, V> {
    
    private final ConcurrentHashMap<K, V> cache = new ConcurrentHashMap<>();
    private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
    private static final int THRESHOLD = 1000;
    
    public V get(K key) {
        V value = cache.get(key);
        if (value != null) {
            return value;
        }
        
        rwLock.readLock().lock();
        try {
            value = cache.get(key);
            if (value != null) {
                return value;
            }
            
            rwLock.readLock().unlock();
            rwLock.writeLock().lock();
            try {
                value = cache.get(key);
                if (value == null) {
                    value = loadFromDatabase(key);
                    cache.put(key, value);
                }
                rwLock.readLock().lock();
            } finally {
                rwLock.writeLock().unlock();
            }
            return value;
        } finally {
            rwLock.readLock().unlock();
        }
    }
    
    private V loadFromDatabase(K key) {
        return null;
    }
}

五、信号量模式

5.1 资源限流

public class ResourceLimiter {
    
    private final Semaphore semaphore;
    
    public ResourceLimiter(int maxConcurrent) {
        this.semaphore = new Semaphore(maxConcurrent);
    }
    
    public void acquire() throws InterruptedException {
        semaphore.acquire();
    }
    
    public void release() {
        semaphore.release();
    }
    
    public int availablePermits() {
        return semaphore.availablePermits();
    }
}

// 使用示例
public class ApiRateLimiter {
    
    private final ResourceLimiter limiter = new ResourceLimiter(100);
    
    public void processRequest(Runnable task) throws InterruptedException {
        limiter.acquire();
        try {
            task.run();
        } finally {
            limiter.release();
        }
    }
}

5.2 多资源协调

public class MultiResourceCoordinator {
    
    private final Semaphore databaseSemaphore = new Semaphore(10);
    private final Semaphore networkSemaphore = new Semaphore(20);
    
    public void executeTask(Runnable task) throws InterruptedException {
        databaseSemaphore.acquire();
        networkSemaphore.acquire();
        
        try {
            task.run();
        } finally {
            networkSemaphore.release();
            databaseSemaphore.release();
        }
    }
}

六、屏障模式

6.1 CyclicBarrier

public class DataProcessingPipeline {
    
    private final CyclicBarrier barrier;
    private final List<DataProcessor> processors;
    
    public DataProcessingPipeline(List<DataProcessor> processors) {
        this.processors = processors;
        this.barrier = new CyclicBarrier(processors.size(), this::aggregateResults);
    }
    
    public void process(Data data) {
        for (DataProcessor processor : processors) {
            executor.submit(() -> {
                processor.process(data);
                try {
                    barrier.await();
                } catch (InterruptedException | BrokenBarrierException e) {
                    Thread.currentThread().interrupt();
                }
            });
        }
    }
    
    private void aggregateResults() {
        System.out.println("All processors completed, aggregating results...");
    }
    
    interface DataProcessor {
        void process(Data data);
    }
}

6.2 CountDownLatch

public class TaskCoordinator {
    
    public void executeTasks(List<Runnable> tasks) throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(tasks.size());
        
        for (Runnable task : tasks) {
            executor.submit(() -> {
                try {
                    task.run();
                } finally {
                    latch.countDown();
                }
            });
        }
        
        latch.await();
        System.out.println("All tasks completed");
    }
}

七、原子操作模式

7.1 AtomicReference

public class NonBlockingStack<T> {
    
    private final AtomicReference<Node<T>> top = new AtomicReference<>();
    
    public void push(T value) {
        Node<T> newNode = new Node<>(value);
        Node<T> oldTop;
        
        do {
            oldTop = top.get();
            newNode.next = oldTop;
        } while (!top.compareAndSet(oldTop, newNode));
    }
    
    public T pop() {
        Node<T> oldTop;
        Node<T> newTop;
        
        do {
            oldTop = top.get();
            if (oldTop == null) {
                return null;
            }
            newTop = oldTop.next;
        } while (!top.compareAndSet(oldTop, newTop));
        
        return oldTop.value;
    }
    
    private static class Node<T> {
        final T value;
        Node<T> next;
        
        Node(T value) {
            this.value = value;
        }
    }
}

7.2 AtomicInteger 计数器

public class ConcurrentCounter {
    
    private final AtomicInteger count = new AtomicInteger(0);
    
    public int increment() {
        return count.incrementAndGet();
    }
    
    public int decrement() {
        return count.decrementAndGet();
    }
    
    public int get() {
        return count.get();
    }
    
    public int add(int delta) {
        return count.addAndGet(delta);
    }
}

八、CompletableFuture 异步模式

8.1 异步任务组合

public class AsyncService {
    
    public CompletableFuture<User> fetchUser(Long userId) {
        return CompletableFuture.supplyAsync(() -> userRepository.findById(userId));
    }
    
    public CompletableFuture<Order> fetchOrder(Long orderId) {
        return CompletableFuture.supplyAsync(() -> orderRepository.findById(orderId));
    }
    
    public CompletableFuture<UserOrderSummary> getUserOrderSummary(Long userId) {
        return fetchUser(userId)
            .thenCompose(user -> fetchOrder(user.getLatestOrderId())
                .thenApply(order -> new UserOrderSummary(user, order)));
    }
    
    public CompletableFuture<List<User>> fetchUsers(List<Long> userIds) {
        List<CompletableFuture<User>> futures = userIds.stream()
            .map(this::fetchUser)
            .collect(Collectors.toList());
        
        return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
            .thenApply(v -> futures.stream()
                .map(CompletableFuture::join)
                .collect(Collectors.toList()));
    }
}

8.2 异常处理

public class AsyncExceptionHandling {
    
    public CompletableFuture<String> processAsync() {
        return CompletableFuture.supplyAsync(this::computeValue)
            .thenApply(this::transformValue)
            .exceptionally(this::handleException)
            .thenApply(this::finalizeResult);
    }
    
    private String computeValue() {
        if (Math.random() > 0.5) {
            throw new RuntimeException("Computation failed");
        }
        return "success";
    }
    
    private String transformValue(String value) {
        return "transformed-" + value;
    }
    
    private String handleException(Throwable e) {
        log.error("Error occurred", e);
        return "fallback-value";
    }
    
    private String finalizeResult(String value) {
        return "final-" + value;
    }
}

九、并发集合模式

9.1 ConcurrentHashMap

public class ConcurrentCache<K, V> {
    
    private final ConcurrentHashMap<K, V> cache = new ConcurrentHashMap<>();
    private final Function<K, V> loader;
    
    public ConcurrentCache(Function<K, V> loader) {
        this.loader = loader;
    }
    
    public V get(K key) {
        return cache.computeIfAbsent(key, loader);
    }
    
    public void invalidate(K key) {
        cache.remove(key);
    }
    
    public void invalidateAll() {
        cache.clear();
    }
}

9.2 CopyOnWriteArrayList

public class ThreadSafeList<E> {
    
    private final CopyOnWriteArrayList<E> list = new CopyOnWriteArrayList<>();
    
    public boolean add(E element) {
        return list.add(element);
    }
    
    public boolean remove(Object o) {
        return list.remove(o);
    }
    
    public E get(int index) {
        return list.get(index);
    }
    
    public void forEach(Consumer<? super E> action) {
        list.forEach(action);
    }
    
    public int size() {
        return list.size();
    }
}

十、实战案例:并发订单处理系统

@Service
public class OrderProcessingService {
    
    private final ExecutorService executorService;
    private final AtomicInteger processingCount = new AtomicInteger(0);
    private final Semaphore semaphore = new Semaphore(50);
    
    public OrderProcessingService(@Qualifier("taskExecutor") ExecutorService executorService) {
        this.executorService = executorService;
    }
    
    public CompletableFuture<Order> processOrderAsync(OrderRequest request) {
        return CompletableFuture.supplyAsync(() -> {
            try {
                semaphore.acquire();
                processingCount.incrementAndGet();
                
                Order order = validateOrder(request);
                order = createOrder(order);
                order = processPayment(order);
                order = sendNotification(order);
                
                return order;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                throw new RuntimeException("Order processing interrupted", e);
            } finally {
                semaphore.release();
                processingCount.decrementAndGet();
            }
        }, executorService);
    }
    
    private Order validateOrder(OrderRequest request) {
        Order order = new Order();
        order.setUserId(request.getUserId());
        order.setTotalAmount(request.getTotalAmount());
        return order;
    }
    
    private Order createOrder(Order order) {
        return orderRepository.save(order);
    }
    
    private Order processPayment(Order order) {
        paymentService.process(order.getId(), order.getTotalAmount());
        order.setStatus("PAID");
        return order;
    }
    
    private Order sendNotification(Order order) {
        notificationService.sendOrderConfirmation(order);
        order.setNotificationSent(true);
        return order;
    }
}

十一、并发编程最佳实践

11.1 线程安全原则

// 1. 最小化共享状态
// 2. 使用线程安全的数据结构
// 3. 避免不必要的同步
// 4. 使用原子操作替代同步块
// 5. 合理使用线程池

11.2 死锁避免

// 1. 按顺序获取锁
public void transferMoney(Account from, Account to, double amount) {
    Account first = from.getId() < to.getId() ? from : to;
    Account second = from.getId() < to.getId() ? to : from;
    
    synchronized (first) {
        synchronized (second) {
            from.withdraw(amount);
            to.deposit(amount);
        }
    }
}

11.3 性能优化

// 1. 使用无锁数据结构
// 2. 减少锁的粒度
// 3. 使用读写锁分离读操作
// 4. 批量操作减少同步次数

十二、总结

本文详细介绍了 Java 中常用的并发编程模式:

  1. 线程池模式:管理线程生命周期,提高资源利用率
  2. 生产者-消费者模式:解耦生产和消费逻辑
  3. 读写锁模式:优化读多写少场景的性能
  4. 信号量模式:控制并发访问数量
  5. 屏障模式:协调多个任务同步执行
  6. 原子操作模式:无锁并发编程
  7. CompletableFuture:异步任务组合与编排
  8. 并发集合:线程安全的数据结构

通过合理应用这些模式,可以构建高效、可靠的并发系统。在实际项目中,需要根据业务场景选择合适的并发策略,平衡性能和复杂度。

掌握并发编程模式不仅能提升代码质量,还能帮助开发者更好地理解 Java 并发库的设计思想,从而在面对复杂并发问题时能够灵活应对。

转载自 CSDN-专业IT技术社区

原文链接:https://blog.csdn.net/alex_goden/article/details/161060490

文章来源转载

评论

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--