创建线程的方法有哪些?
1 个回答
春宵苦短日高起,从此君王不早朝。空霖# 1) 直接创建线程 * **继承 `Thread`** ```java class MyThread extends Thread { public void run() { /* do work */ } } new MyThread().start(); ``` 优点:简单;缺点:不利于复用,不能再继承别的类。 * **实现 `Runnable` + `Thread`** ```java Runnable task = () -> { /* do work */ }; new Thread(task, "t1").start(); ``` 推荐度高于继承 `Thread`;无返回值。 * **实现 `Callable`(有返回值)+ `FutureTask` + `Thread`** ```java Callable<Integer> c = () -> 42; FutureTask<Integer> f = new FutureTask<>(c); new Thread(f).start(); Integer r = f.get(); ``` # 2) 线程池(生产最常用) * **`ExecutorService`(统一入口)** ```java ExecutorService pool = Executors.newFixedThreadPool(8); pool.submit(() -> {/* Runnable */}); Future<Integer> f = pool.submit(() -> 42); // Callable pool.shutdown(); ``` * **`ThreadPoolExecutor`(手动可控,生产首选)** ```java ExecutorService pool = new ThreadPoolExecutor( 8, 16, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(1000), r -> { Thread t = new Thread(r, "biz-"); t.setDaemon(false); return t; }, new ThreadPoolExecutor.AbortPolicy() ); ``` 可精细控制核心/最大线程、队列、拒绝策略、命名等。 * **定时/周期任务:`ScheduledExecutorService`** ```java ScheduledExecutorService sch = Executors.newScheduledThreadPool(2); sch.scheduleAtFixedRate(() -> {/* job */}, 1, 5, TimeUnit.SECONDS); ``` 替代旧的 `Timer/TimerTask`(后者单线程,异常会终止)。 # 3) 高层并发框架 * **`CompletableFuture`(异步编排)** ```java CompletableFuture.supplyAsync(() -> 42) .thenApply(x -> x + 1) .thenAccept(System.out::println); ``` 可传入自定义线程池:`supplyAsync(supplier, pool)`。 * **`ForkJoinPool` / `RecursiveTask`(分治、工作窃取)** ```java class SumTask extends RecursiveTask<Long> { int[] arr; int l, r; protected Long compute() { /* 分治 */ return 0L; } } ForkJoinPool fj = new ForkJoinPool(); fj.invoke(new SumTask(/*...*/)); ``` * **并行流 `parallelStream()`(底层用公共 ForkJoinPool)** ```java list.parallelStream().map(x -> x + 1).forEach(System.out::println); ``` 注意别与应用线程池争用同一个公共池导致干扰。 # 4) 虚拟线程(Loom,JDK 21+) * **直接创建虚拟线程** ```java Thread.ofVirtual().name("vt-").start(() -> {/* I/O 密集更香 */}); ``` * **每任务一个虚拟线程的执行器** ```java try (ExecutorService vtp = Executors.newVirtualThreadPerTaskExecutor()) { vtp.submit(() -> {/* task */}); } ``` 优点:超轻量,适合大量阻塞型 I/O;缺点:需新 JDK,配套库要兼容阻塞语义。 # 5) 其他/补充 * **`ThreadFactory`**:自定义线程名、守护/非守护、优先级、异常处理。 * **`Timer/TimerTask`**:旧方案,不推荐;用 `ScheduledExecutorService` 代替。 ## 选型速记 * 简单一次性任务:`new Thread(Runnable).start()` * 有返回值/要拿结果:`Callable`/`FutureTask` 或 `ExecutorService.submit(Callable)` * 生产环境通用:**`ThreadPoolExecutor`**(显式参数+监控) * 定时任务:`ScheduledExecutorService` * 异步编排:`CompletableFuture` * 计算密集分治:`ForkJoinPool` * 大量 I/O 并发且 JDK≥21:**虚拟线程** ## 小坑提示 * 不要无限制 `new Thread()`;优先线程池控制并发与背压。 * 给线程起名、设置 `UncaughtExceptionHandler`,便于排错。 * 线程池的**队列/拒绝策略**要和业务背压策略匹配。 * 并行流默认共用全局池,服务端慎用(可用 `ForkJoinPool` 自定义)。 * 虚拟线程适合阻塞 I/O;CPU 密集型依旧遵循 CPU 核数配置。发布于 2025-08-13 14:08 •IP属地 上海举报评论收藏
公众号进入网站体验更佳

