当前位置:首页 » 《关于电脑》 » 正文

【面试宝典】Java中创建线程池的几种方式以及区别

28 人参与  2024年11月14日 14:41  分类 : 《关于电脑》  评论

点击全文阅读


在这里插入图片描述

579a429daf314744b995f37351b46548

强烈推荐

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站:人工智能

b004071ozy_05_amzn

创建线程池有多种方式,主要通过 Java 的 java.util.concurrent 包提供的 Executors 工具类来实现。以下是几种常见的线程池类型及其区别:

1. FixedThreadPool

//创建一个固定大小的线程池,模拟提交 10 个任务到线程池。import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class FixedThreadPoolExample {    public static void main(String[] args) {        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3); // 创建一个具有3个线程的固定线程池                for (int i = 1; i <= 10; i++) {            final int task = i;            fixedThreadPool.execute(() -> {                System.out.println("执行任务 " + task + ",线程:" + Thread.currentThread().getName());            });        }                fixedThreadPool.shutdown();    }}

特点:创建一个固定大小的线程池,池中始终保持指定数量的线程。

适用场景:适用于固定并发数的任务,比如定量的短期并发任务。

优点:能够有效地控制线程数量,避免资源消耗过多。

缺点:如果所有线程都在执行任务,而新的任务不断提交,可能会造成等待队列过长。

2. CachedThreadPool

//创建一个缓存线程池来处理任务,模拟并发执行 10 个任务import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class CachedThreadPoolExample {    public static void main(String[] args) {        ExecutorService cachedThreadPool = Executors.newCachedThreadPool();                for (int i = 1; i <= 10; i++) {            final int task = i;            cachedThreadPool.execute(() -> {                System.out.println("执行任务 " + task + ",线程:" + Thread.currentThread().getName());            });        }                cachedThreadPool.shutdown();    }}
特点:创建一个可以根据需要自动扩展的线程池,当线程空闲 60 秒后会被回收。适用场景:适合执行大量耗时较短的异步任务。优点:线程数量不受限制(受系统资源限制),对于任务短小、并发量大但不稳定的场景效果较好。缺点:如果任务增长过快,会创建大量线程,可能会造成 OOM(Out of Memory)异常。

3. SingleThreadExecutor

//创建一个单线程线程池,顺序执行多个任务。import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class SingleThreadExecutorExample {    public static void main(String[] args) {        ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();                for (int i = 1; i <= 5; i++) {            final int task = i;            singleThreadExecutor.execute(() -> {                System.out.println("执行任务 " + task + ",线程:" + Thread.currentThread().getName());            });        }                singleThreadExecutor.shutdown();    }}
特点:创建单线程化的线程池,始终只有一个工作线程。适用场景:适用于需要保证任务顺序执行的场景,避免多线程并发的复杂性。优点:可以保证任务按顺序执行,适合单一任务队列。缺点:性能较低,不适合需要高并发的场景。

4. ScheduledThreadPool

//创建一个支持定时和周期性执行任务的线程池,示例任务每隔 2 秒执行一次,共执行 3 次。import java.util.concurrent.Executors;import java.util.concurrent.ScheduledExecutorService;import java.util.concurrent.TimeUnit;public class ScheduledThreadPoolExample {    public static void main(String[] args) {        ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(2); // 创建一个有2个线程的定时线程池                scheduledThreadPool.scheduleAtFixedRate(() -> {            System.out.println("定时任务执行,线程:" + Thread.currentThread().getName());        }, 0, 2, TimeUnit.SECONDS); // 0秒延迟后开始,每隔2秒执行一次任务                // 程序运行5秒后关闭线程池        try {            Thread.sleep(5000);        } catch (InterruptedException e) {            e.printStackTrace();        }                scheduledThreadPool.shutdown();    }}
特点:创建一个支持定时或周期性任务执行的线程池。适用场景:适合执行定时任务或周期性任务,比如定时器、定时检查等。优点:可以方便地实现周期性任务管理。缺点:对高并发任务的处理能力较弱,通常用于任务量不大的场景。

5. WorkStealingPool(Java 8 引入)

//创建一个基于任务分解的线程池来并行执行多个任务,适合处理需要拆分的小任务。import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.TimeUnit;public class WorkStealingPoolExample {    public static void main(String[] args) throws InterruptedException {        ExecutorService workStealingPool = Executors.newWorkStealingPool(); // 创建默认线程数为CPU核心数的工作窃取线程池                for (int i = 1; i <= 8; i++) {            final int task = i;            workStealingPool.submit(() -> {                System.out.println("执行任务 " + task + ",线程:" + Thread.currentThread().getName());                try {                    TimeUnit.SECONDS.sleep(1);                } catch (InterruptedException e) {                    e.printStackTrace();                }            });        }                // 让主线程等待子任务执行完成        workStealingPool.awaitTermination(3, TimeUnit.SECONDS);        workStealingPool.shutdown();    }}
特点:基于 ForkJoinPool 实现,适用于大任务拆分成小任务的并行处理。线程数默认为处理器核心数。适用场景:适合处理较为复杂的并行任务,比如分治算法。优点:通过“工作窃取”算法实现任务的动态负载均衡,能够有效提升多核 CPU 的利用率。缺点:由于线程数不固定,可能对资源使用较多,不适合所有应用。

区别总结

线程池类型线程数量控制特点适用场景
FixedThreadPool固定数量固定线程数,适合稳定的任务并发固定并发任务
CachedThreadPool自动扩展动态扩展,空闲线程自动回收,适合任务短小但并发量不稳定短期的异步并发任务
SingleThreadExecutor单一线程单线程顺序执行任务,保证顺序顺序执行的任务
ScheduledThreadPool可控核心线程数支持定时或周期性任务定时任务、周期性任务
WorkStealingPool默认 CPU 核数基于任务拆分并行处理,提高多核 CPU 利用率并行计算和多任务的分解

专栏推荐

大佬们可以收藏以备不时之需:

Spring Boot 专栏:http://t.csdnimg.cn/peKde

ChatGPT 专栏:http://t.csdnimg.cn/cU0na

Java 专栏:http://t.csdnimg.cn/YUz5e

Go 专栏:http://t.csdnimg.cn/Jfryo

Netty 专栏:http://t.csdnimg.cn/0Mp1H

Redis 专栏:http://t.csdnimg.cn/JuTue

Mysql 专栏:http://t.csdnimg.cn/p1zU9

架构之路 专栏:http://t.csdnimg.cn/bXAPS

csdn-end

博主深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新JAVA全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。

这套1T的JAVA学习资料是为真正想在技术道路上突围的人准备的,内容覆盖全面:从各大厂的面试题到1000多个专业简历模板,从就业班到进阶课程,再到架构师实战与全栈高薪课程,帮助你从基础到高阶一步步提升!

无论是找工作还是技能进阶,这份VIP资料都是你不可错过的利器!

部分内容:

1

2

3

8

9

10

如有需要加下方V了解详情,备注:JAVA开发VIP资料。


点击全文阅读


本文链接:http://zhangshiyu.com/post/186045.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1