
Java常见线程池简介、线程池创建、线程池原理、死锁产生原因及排查
线程池创建后,立即处理任务。 任务提交时: 处理完成后,线程返回到队列获取下一个任务。 空闲线程若超过核心线程数,将超出部分线程销毁,当任务完成后,最小化到核心线程数。 使用堆转储工具(如开源工具JDK的Sampler)。 导出线程堆转储文件,查看处于等待状态的线程。 识别死锁资源,分析原因。 优化代码,减少资源竞争或顺序依赖。
发布日期:2021-05-15 00:00:42
浏览次数:29
分类:精选文章
本文共 2598 字,大约阅读时间需要 8 分钟。
线程池与死锁深度分析
一、线程池创建与执行机制
1. 线程池是线程的管理池
- 核心线程数与非核心线程数:核心线程为专门获取任务并执行的线程,非核心线程用于处理超出核心线程负载的任务。
- 任务处理策略:任务到达时,首先检查是否有核心线程空闲,否则将任务加入队列。队列满时,若超过最大线程数,采用饱和策略。
2. 阻塞队列类型对比
- ArrayBlockingQueue:基于数组实现的有界FIFO队列,特点是固定大小和内存限制。
- LinkedBlockingQueue:基于链表实现,支持大容量,性能优于ArrayBlockingQueue。
- DelayQueue:支持延迟执行,按执行时间排序。
- SynchronousQueue:不存储任务,要求生产者与消费者同步,效率更高。
3. 线程池执行流程
- 若核心线程数未达最大,直接启动新线程。
- 若核心线程已满,存入队列。
- 若队列满,且总线程未达最大值,扩展非核心线程。
4. 常见线程池类型应用介绍
- newFixedThreadPool:定长线程池,适合长期任务。
- newCachedThreadPool:可缓存线程池,适合短期任务。
- newSingleThreadExecutor:单线程池,顺序执行任务。
- newScheduledThreadPool:定长线程池,支持定时任务。
二、线程池创建方法实例
// 创建年度线程池ThreadPoolExecutor threadPool = new ThreadPoolExecutor( 2, // 核心线程数 5, // 最大线程数 1L, // 空闲时间(秒) TimeUnit.SECONDS, new LinkedBlockingDeque<>(3), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
三、饱和拒绝策略
// 饱和拒绝策略选择ThreadPoolExecutor threadPool = new ThreadPoolExecutor( 2, 5, 1L, TimeUnit.SECONDS, new SynchronousQueue(), Executors.defaultThreadFactory(), new CallerRunsPolicy());
四、死锁实例
// 死锁示例代码class ThreadA implements Runnable { private String lockA, lockB; public ThreadA(String lockA, String lockB) { this.lockA = lockA; this.lockB = lockB; } @Override public void run() { synchronized (lockA) { System.out.println(Thread.currentThread().getName() + "持有了lockA,尝试获取lockB"); try { synchronized (lockB) { System.out.println(Thread.currentThread().getName() + "已经获取了lockB"); } } catch (InterruptedException e) { System.out.println("线程被打断:" + Thread.currentThread().getName()); Thread.currentThread().interrupt(); } } }}public class DeadlockTest { public static void main(String[] args) throws InterruptedException, ExecutionException { String lockA = "lockA", lockB = "lockB"; Thread thread1 = new Thread(new ThreadA(lockA, lockB), "(locale1)"); Thread thread2 = new Thread(new ThreadA(lockB, lockA), "(locale2)"); thread1.start(); thread2.start(); try { Thread.sleep(2000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } System.out.println("主线程等待死锁情况"); }}
五、死锁排查方法
通过以上方法,可以有效识别并消除死锁问题,确保系统稳定运行。
发表评论
最新留言
路过,博主的博客真漂亮。。
[***.116.15.85]2025年05月04日 01时05分26秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
Flex 布局的自适应子项内容过长导致其被撑大问题
2019-03-09
PL/SQL 动态Sql拼接where条件
2019-03-09
Lua-table 一种更少访问的安全取值方式
2019-03-09
虚函数
2019-03-09
斐波那契数列两种算法的时间复杂度
2019-03-09
【自学Flutter】4.1 Material Design字体图标的使用(icon)
2019-03-09
C++清空队列(queue)方法
2019-03-09
【换行符】什么时候用cin.get()吃掉输入流中的换行符
2019-03-09
【二叉树】已知后序与中序求先序
2019-03-09
解决Nginx 404 not found问题
2019-03-09
广东外语外贸大学第三届网络安全大赛Writeup
2019-03-09
hadoop 分布式文件系统的计算和高可用
2019-03-09
【Linux】VMware Workstation 不可恢复错误: (vcpu-0)
2019-03-09
VS中 fatal error LNK1123: 转换到 COFF 期间失败 的解决方法
2019-03-09
ant design pro v5去掉右边content区域的水印
2019-03-09
JavaScript——使用iterator遍历迭代map,set集合元素
2019-03-09
Course Schedule II
2019-03-10
C#中文转换成拼音
2019-03-10
C++错误笔记
2019-03-10