Java 线程池创建方式大揭秘!互联网大厂后端开发必看
yund56 2025-05-03 16:59 27 浏览
你在互联网大厂做后端开发时,在使用 Java 线程池方面,有没有遇到过不知道该怎么创建的情况呢?项目需求一来,多线程任务一布置,线程池该如何正确创建,成了很多开发者头疼的问题。今天,咱们就深入聊聊 Java 中线程池的创建方式,帮你彻底解决这个困扰!
互联网大厂后端开发为什么离不开线程池?
在互联网大厂的后端开发场景中,高并发、大数据量处理是家常便饭。以电商平台的大促活动为例,海量用户同时下单、查询订单信息,服务器需要同时处理成千上万的请求。这时候,线程池就显得尤为重要。如果没有合理使用线程池,要么创建过多线程导致资源耗尽,服务器崩溃;要么线程数量不足,任务堆积,用户等待时间过长,严重影响用户体验。而且,Java 作为互联网后端开发的主流语言之一,其线程池机制是保障程序高效稳定运行的关键。但很多开发者对于线程池的创建,仅仅停留在一知半解的层面,这就很容易在实际开发中埋下隐患。
Java 线程池创建方式详解
Java 中线程池的创建方式主要有以下几种:
使用 Executors 工厂类创建
FixedThreadPool
通过
Executors.newFixedThreadPool(int nThreads)方法创建,它会创建一个固定大小的线程池,池中线程数量固定不变。当有新任务提交时,如果线程池中有空闲线程,就会立即执行任务;如果没有空闲线程,任务会被暂存到一个阻塞队列中,等待有线程空闲时再执行。
示例:假设我们有一个电商订单处理系统,需要同时处理 10 个订单的支付请求,每个支付请求都需要一个线程来处理。为了避免线程过多导致资源竞争,我们可以使用 FixedThreadPool 来创建一个固定大小为 10 的线程池。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class FixedThreadPoolExample {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(10);
for (int i = 0; i < 20; i++) {
final int orderId = i;
executorService.submit(() -> {
// 模拟处理订单支付逻辑
System.out.println("处理订单 " + orderId + " 的支付请求");
});
}
executorService.shutdown();
}
}
这种线程池适用于处理固定数量并发任务的场景,比如数据库连接池,保证固定数量的线程同时访问数据库,避免资源竞争。
CachedThreadPool
使用
Executors.newCachedThreadPool()创建,它是一个可缓存的线程池。如果线程池长度超过处理需求,可灵活回收空闲线程,若无可回收,则新建线程。它比较适合处理执行时间短、突发性大量请求的任务。
示例:在一个日志收集系统中,会不定期有大量的日志记录任务产生。我们可以使用 CachedThreadPool 来处理这些任务。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CachedThreadPoolExample {
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0; i < 100; i++) {
final int logId = i;
executorService.submit(() -> {
// 模拟记录日志逻辑
System.out.println("记录日志 " + logId);
});
}
executorService.shutdown();
}
}
任务执行完线程就可以被回收,下次有新任务再来时又能快速创建新线程处理。
SingleThreadExecutor
通过
Executors.newSingleThreadExecutor()创建,它只有一个工作线程来执行任务。所有任务按照提交顺序依次执行,保证任务执行的顺序性。
示例:在文件按顺序读写操作的场景中,使用 SingleThreadExecutor 能确保数据的读写顺序。比如,我们要按顺序读取一系列文本文件的内容。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class SingleThreadExecutorExample {
public static void main(String[] args) {
ExecutorService executorService = Executors.newSingleThreadExecutor();
String[] fileNames = {"file1.txt", "file2.txt", "file3.txt"};
for (String fileName : fileNames) {
final String name = fileName;
executorService.submit(() -> {
// 模拟按顺序读取文件内容逻辑
System.out.println("读取文件 " + name + " 的内容");
});
}
executorService.shutdown();
}
}
ScheduledThreadPool
使用
Executors.newScheduledThreadPool(int corePoolSize)创建,它可以实现定时任务和周期性任务的执行。
示例:在电商系统中,每天凌晨 2 点需要统计前一天的销售数据。我们可以使用 ScheduledThreadPool 来实现这个定时任务。
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 scheduledExecutorService = Executors.newScheduledThreadPool(1);
scheduledExecutorService.scheduleAtFixedRate(() -> {
// 模拟统计销售数据逻辑
System.out.println("统计销售数据");
}, 0, 1, TimeUnit.DAYS);
}
}
通过schedule()方法可以延迟执行任务,scheduleAtFixedRate()和scheduleWithFixedDelay()方法可以实现周期性任务的执行。
通过 ThreadPoolExecutor 类手动创建
ThreadPoolExecutor 是创建线程池的核心类,通过它我们可以更灵活地配置线程池的参数。它的构造函数如下:
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
- corePoolSize:核心线程数,线程池创建后默认会创建的线程数量,即使这些线程处于空闲状态,也不会被销毁(除非设置了allowCoreThreadTimeOut为true)。
- maximumPoolSize:最大线程数,线程池中允许存在的最大线程数量。当任务队列满了且工作线程数小于最大线程数时,线程池会创建新的线程来处理任务。
- keepAliveTime:空闲线程的存活时间。当线程池中的线程数量大于核心线程数时,如果某个线程空闲时间超过keepAliveTime,就会被销毁,直到线程池中的线程数量等于核心线程数。
- unit:keepAliveTime的时间单位,如TimeUnit.MILLISECONDS(毫秒)、TimeUnit.SECONDS(秒)等。
- workQueue:任务队列,用于存放等待执行的任务。常见的有ArrayBlockingQueue(有界队列)、LinkedBlockingQueue(无界队列)等。
- threadFactory:线程工厂,用于创建线程,一般使用默认的线程工厂即可,也可以自定义线程工厂来设置线程的名称、优先级等属性。
- handler:拒绝策略,当任务队列已满且线程数达到最大线程数时,新提交的任务会被拒绝,此时就需要通过拒绝策略来处理这些被拒绝的任务。常见的拒绝策略有AbortPolicy(抛出异常)、CallerRunsPolicy(在调用者线程中执行任务)、DiscardPolicy(丢弃任务)、DiscardOldestPolicy(丢弃队列中最老的任务,然后重新提交当前任务)。
示例:我们创建一个线程池,核心线程数为 5,最大线程数为 10,空闲线程存活时间为 60 秒,任务队列使用有界的ArrayBlockingQueue,容量为 20,拒绝策略采用CallerRunsPolicy。
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class ThreadPoolExecutorExample {
public static void main(String[] args) {
BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(20);
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
5,
10,
60,
TimeUnit.SECONDS,
workQueue,
new ThreadPoolExecutor.CallerRunsPolicy()
);
for (int i = 0; i < 50; i++) {
final int taskId = i;
threadPoolExecutor.submit(() -> {
// 模拟任务执行逻辑
System.out.println("执行任务 " + taskId);
});
}
threadPoolExecutor.shutdown();
}
}
手动创建线程池虽然相对复杂,但却能让我们根据具体的业务场景,精准地配置各项参数,以达到最佳的性能和资源利用效果。
总结
以上就是 Java 中线程池常见的创建方式。在互联网大厂后端开发中,掌握这些创建方式,合理配置线程池参数,能让你的程序在高并发场景下更加稳定、高效地运行。希望大家都能熟练运用线程池,在项目开发中少踩坑!如果你在实际使用线程池的过程中有任何问题,或者有独特的经验,欢迎在评论区留言分享,咱们一起交流探讨,共同进步!
相关推荐
- 豆包编程能力升级:支持HTML代码实时预览、交互
-
IT之家3月19日消息,IT之家从豆包官方获悉,豆包宣布AI编程功能迎来三项升级,包括HTML预览、Python运行、生成完整项目。据介绍,目前豆包支持HTML代码实时预览和交互...
- 1898款游戏!80、90回忆杀,重温旧梦,快速搭建中文DOS游戏服务
-
本内容来源于@什么值得买APP,观点仅代表作者本人|作者:羊刀仙大家好,我是羊刀仙。本期来介绍一个特别情怀向的游戏项目:chinese-dos-games。这套包含1898款经典中文DOS游戏的合集...
- 利用 SVG 文件内的 HTML 代码进行网络钓鱼攻击
-
随着时间的推移,网络钓鱼攻击的技术越来越精妙,旨在欺骗用户并规避安全措施。攻击者会使用欺骗性的URL重定向策略,例如将恶意网站地址附加到看似安全的链接后,在PDF中嵌入链接,以及发送HTML...
- aardio + AI 大模型自动编写 Python 代码、网页前端代码的经验与技巧
-
在AI时代,老式的编程习惯完全被颠覆。原来可能要一大堆插件或工具辛苦堆出来的程序,现在只要把AI调教好了就行。aardio支持调用十几种编程语言,这很适合发挥AI大模型的优势。对于AI...
- 用AI制作游戏就是如此简单!
-
很多人不知道如何利用AI提高效率,不知道AI能帮我们做什么,其实可以让我们实现很多自己根本不懂的领域取得直观体验,比如利用DS或者豆包,输入“我想做一个简单的单机俄罗斯方块游戏”,AI会给出phtho...
- 不会写代码?教你用DeepSeek 三步做出小游戏
-
如今,借助人工智能技术,哪怕你完全看不懂代码,也能通过DeepSeek制作出属于自己的网页版大鱼吃小鱼游戏。接下来,就为大家详细介绍制作过程。第一步、向DeepSeek描述需求为何要做网页版的...
- 《暗黑1》被移植成网页游戏 可在浏览器上玩了
-
《暗黑1》,这款1996年发售的“鼠标杀手”砍杀游戏,现在可以在浏览器上玩了。国外专注暴雪游戏的Rivsoft分享了一个《暗黑1》的共享版本,该版本只包含地下城的头2个地区和三个角色职业中的一个。不...
- 网页代码过滤 轻松获取专辑目录
-
通过过滤网页代码,可以将网页上显示不全的长文件名列表完整地提取出来。我有一个含有75个视频文件的《中医诊断学》课件,文件名是以01.RMVB、02.RMVB……75.RMVB这种格式命名的。我希望能找...
- IDEA 2021首个大版本发布,Java开发者感动哭了(附新亮点演示)
-
工欲善其事,必先利其器!就在不久之前,Java领域的开发神器IntelliJIDEA终于迎来2021年的一个重要的大版本更新:IntelliJIDEA2021.1。现如今大量的Java开发者深度...
- View Source:在 iOS 上轻松查看网页源代码
-
在移动互联网时代,移动端的应用和web体验都尤为重要,在PC上有很多web前端工具可以选择,而在移动端貌似就少之又少了,在NEXT出现的ViewSource能帮你在iOS上查看...
- 当我们《寻找房祖名》,我们能找到什么?
-
游戏葡萄原创专稿,未经允许请勿转载柯震东,因为在九把刀电影《那些年我们追过的女孩》中饰演男主角柯景腾而走红的台湾影星,在昨天被爆出了和著名演员成龙之子房祖名吸毒被抓的丑闻,一时间相关讨论席卷社交网络。...
- 多用途游戏娱乐新闻网站HTML5模板
-
Retnews是一个响应式的HTML新闻,博客,杂志网站模板,可以使用这套前端模板简约很多设计的工作。模板有许多特性适合流行的主题商业、时尚,游戏,娱乐,生活方式、体育、科技、政治、旅行、天气、视频等...
- 简约好看的个人引导页HTML源码下载
-
源码介绍一款非常简约好看的个人引导页HTML源码,非常适合个人主页以及个人导航使用,纯HTML不需要数据库,上传服务器即可使用!...
- 教你如何在微信公共平台上插入小游戏(图文教程)
-
很多玩微信公共平台的朋友都想在公共平台上面插入几个小游戏,用来跟用户之间互动,这里花生来分享一下如何在微信公共平台上插入游戏,以及如何制作html5微信小游戏。首先是找游戏,总共有三个方法,本人比较倾...
- html5重力感应剖析附源码
-
下面是测试html5重力感应的demohttp://bbs.qietu.com/html/zhongli/http://www.qietu.com/html/f2/qqqianbao/demo2是切图...
- 一周热门
- 最近发表
- 标签列表
-
- filter函数js (37)
- filter函数excel用不了 (73)
- 商城开发 (40)
- 影视网站免费源码最新版 (57)
- 影视资源api接口 (46)
- 网站留言板代码大全 (56)
- java版软件下载 (52)
- java教材电子课本下载 (48)
- 0基础编程从什么开始学 (50)
- java是用来干嘛的 (51)
- it入门应该学什么 (55)
- java线上课程 (55)
- 学java的软件叫什么软件 (38)
- 程序开发软件有哪些 (53)
- 软件培训 (59)
- 机器人编程代码大全 (50)
- 少儿编程教程免费 (45)
- 新代系统编程教学 (61)
- 共创世界编程网站 (38)
- 亲测源码 (36)
- 三角函数积分公式表 (35)
- 函数的表示方法 (34)
- 表格乘法的公式怎么设置 (34)
- sumif函数的例子 (34)
- 图片素材 (36)