Java中的并发与多线程:高级技术

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Java中的并发与多线程:高级水平

\n\n

Java中的多线程是最强大同时也最复杂的主题之一。在初级阶段,我们使用synchronized和Thread,但要构建高性能、可扩展的系统,需要更深入的理解。本文将探讨高级并发机制:线程池、ForkJoinPool、使用CompletableFuture进行异步编程、锁的精细调优以及内存操作。内容面向已掌握多线程基础的开发者。

\n\n

1. 线程池的高级使用:ExecutorService与配置

\n\n

使用ExecutorService是工业级开发的标准做法。然而,标准的Executors.newFixedThreadPool(10)并非总是适用。我们来探讨ThreadPoolExecutor的精细配置。

\n\n
import java.util.concurrent.*;\n\npublic class CustomThreadPool {\n    public static void main(String[] args) {\n        int corePoolSize = 4;\n        int maxPoolSize = 8;\n        long keepAliveTime = 30;\n        TimeUnit unit = TimeUnit.SECONDS;\n        BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(100);\n\n        ThreadPoolExecutor executor = new ThreadPoolExecutor(\n                corePoolSize,\n                maxPoolSize,\n                keepAliveTime,\n                unit,\n                workQueue,\n                new ThreadPoolExecutor.CallerRunsPolicy() // 饱和策略\n        );\n\n        // 监控线程池状态\n        executor.submit(() -> {\n            System.out.println("活跃线程数: " + executor.getActiveCount());\n            System.out.println("已完成任务数: " + executor.getCompletedTaskCount());\n        });\n\n        executor.shutdown();\n    }\n}
\n\n

关键参数:

\n
    \n
  • corePoolSize — 即使没有任务也保持的最小线程数。
  • \n
  • maxPoolSize — 最大线程数。
  • \n
  • keepAliveTime — 多余线程的存活时间。
  • \n
  • workQueue — 任务队列。使用有界ArrayBlockingQueue可防止内存溢出。
  • \n
  • 饱和策略 — 当队列已满且所有线程都忙碌时的处理方式。CallerRunsPolicy会减慢调用线程的速度。
  • \n
\n\n

对于长时间I/O任务,建议增大corePoolSize;对于CPU密集型任务,应参考Runtime.getRuntime().availableProcessors()。

\n\n

2. ForkJoinPool与递归任务

\n\n

ForkJoinPool是一个专门用于可分解为子任务(分而治之)的线程池。它高效地利用了工作窃取(work stealing)机制。

\n\n

示例:递归计算数组元素之和。

\n\n
import java.util.concurrent.RecursiveTask;\nimport java.util.concurrent.ForkJoinPool;\n\npublic class SumTask extends RecursiveTask<Long> {\n    private static final int THRESHOLD = 1000;\n    private final int[] array;\n    private final int start;\n    private final int end;\n\n    public SumTask(int[] array, int start, int end) {\n        this.array = array;\n        this.start = start;\n        this.end = end;\n    }\n\n    @Override\n    protected Long compute() {\n        if (end - start <= THRESHOLD) {\n            long sum = 0;\n            for (int i = start; i < end; i++) {\n                sum += array[i];\n            }\n            return sum;\n        }\n        int mid = (start + end) / 2;\n        SumTask leftTask = new SumTask(array, start, mid);\n        SumTask rightTask = new SumTask(array, mid, end);\n\n        leftTask.fork(); // 异步启动\n        long rightResult = rightTask.compute(); // 计算                

博客

书籍推荐