**高并发、微服务 、性能调优实战案例100讲，所有案例均源于个人工作实战，均配合代码落地**

加我微信：itsoku，所有案例均提供在线答疑。



# 第54节 性能调优：线程死锁相关问题

非常实用的一节，先收藏点赞，慢慢看。

<span style="font-weight:bold; color:red">目前整个课程59块钱，100个案例，含所有源码 & 文档 & 技术支持，可点击左下角小黄车了解</span>



# 1、什么是线程死锁？

两个或多个线程在执行过程中，因争夺共享资源而被阻塞，且无法继续执行下去的一种状态。



# 2、示例

比如下面这个案例，定义了两个线程：thread1和thread2

- thread1对resource1上锁，然后尝试获取resource2的锁；
- thread2对resource2上锁，然后尝试获取resource1的锁；

运行下，2个线程会相互等待，出现死锁

```java
public class DeadlockDemo {
    // 创建两个共享资源
    private static final String resource1 = new String();
    private static final Object resource2 = new Object();

    public static void main(String[] args) {
        /**
         * 两个线程
         * thread1对resource1上锁，然后尝试获取resource2的锁；
         * thread2对resource2上锁，然后尝试获取resource1的锁；
         * 2个线程会相互等待，出现死锁
         */
        Thread thread1 = new Thread(() -> {
            synchronized (resource1) {
                System.out.println("Thread 1: Locked resource 1");

                try {
                    Thread.sleep(100); // 假设这里有其他操作，需要一些时间
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                System.out.println("Thread 1: Attempting to lock resource 2");

                //尝试索取resource2的锁
                synchronized (resource2) {
                    System.out.println("Thread 1: Locked resource 2");
                }
            }
        }, "thread1");

        Thread thread2 = new Thread(() -> {
            synchronized (resource2) {
                System.out.println("Thread 2: Locked resource 2");

                try {
                    Thread.sleep(100); // 假设这里有其他操作，需要一些时间
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                //尝试索取resource1的锁
                System.out.println("Thread 2: Attempting to lock resource 1");
                synchronized (resource1) {
                    System.out.println("Thread 2: Locked resource 1");
                }
            }
        }, "thread2");

        // 启动线程
        thread1.start();
        thread2.start();
    }
}
```



# 3、死锁会导致什么问题？

线程阻塞，这个是最直接的影响

若有大量线程死锁，会导致线程被耗尽，最终将导致系统崩溃，无法对外提供服务



# 4、如何发现死锁？

需要依赖监控系统：监控系统可以定时使用jstack命令采集线程信息，jstack命令中可以查看到死锁的详细信息，进行告警，人工介入干预。



# 5、3种方法定位死锁代码

## 1）方案1：jps+jstack命令

- jps查找进程id

  > jdk自带工具，可以查看所有的java进程

  ```shell
  jsp
  ```

- jstack命令查看死锁信息

  > jdk自带的工具，可以查看某个java进程中所有的线程快照，可以看到死锁的相信信息

  ```shell
  jstack 进程id
  ```

## 2）方案2：jvisualvm

> jvisualvm工具：jdk自带的工具

cmd中运行：jvisualvm，即可打开这个工具

![image-20240702114921880](img/image-20240702114921880.png)

![image-20240702114947327](img/image-20240702114947327.png)

## 3）方案3：arthas

> arthas：阿里提供的一个特好用的jvm线上问题诊断利器，详情见：https://arthas.aliyun.com/doc/quick-start.html



# 6、死锁常见的解决方案

为了解决Java中的线程死锁问题，可以采取以下几种策略：

1. **避免使用多个锁**：通过合理设计程序，尽量避免多个线程同时争用相同的资源
2. **保持锁的有序性**：当使用多个锁时，保持所有线程获取锁的顺序一致，以避免因顺序不一致而导致的死锁
3. **超时等待**：设置锁的超时时间，当等待超过一定时间后，放弃对锁的请求，进行其他的处理
4. **死锁检测和恢复**：使用工具来检测和恢复死锁，一旦检测到死锁，可以通过中断线程、释放资源等方式来恢复程序的执行



# 获取，源码 & 文档 & 技术支持

源码在 lesson054 这个模块中，需要的小伙伴可以加我微信：itsoku，获取。



# 高并发 & 微服务 & 性能调优实战案例100讲

## 已更新 54 节课

<span style="font-weight:bold; color:red">目前整个课程59块钱，含所有源码 & 文档 & 技术支持，一杯咖啡的价格，还没下手的朋友，赶紧了，马上要涨价了</span>。

```java
1. 分片上传实战
2. 通用并发处理工具类实战
3. 实现一个好用接口性能压测工具类
4. 超卖问题的4种解决方案，也是防止并发修改数据出错的通用方案
5. Semaphore实现接口限流实战
6. 并行查询，优化接口响应速度实战
7. 接口性能优化之大事务优化
8. 通用的Excel动态导出功能实战
9. 手写线程池管理器，管理&监控所有线程池
10. 动态线程池
11. SpringBoot实现动态Job实战
12. 并行查询，性能优化利器，可能有坑
13. 幂等的4种解决方案，吃透幂等性问题
14. 接口通用返回值设计与实现
15. 接口太多，各种dto、vo不计其数，如何命名？
16. 一个业务太复杂了，方法太多，如何传参？
17. 接口报错，如何快速定位日志？
18. 线程数据共享必学的3个工具类：ThreadLocal、InheritableThreadLocal、TransmittableThreadLocal
19. 通过AOP统一打印请求链路日志，排错效率飞升
20. 大批量任务处理常见的方案（模拟余额宝发放收益）
21. 并发环境下，如何验证代码是否正常？
22. MySql和Redis数据一致性
23. SpringBoot数据脱敏优雅设计与实现
24. 一行代码搞定系统操作日志
25. Aop简化MyBatis分页功能
26. ThreadLocal 遇到线程池有大坑 & 通用解决方案
27. SpringBoot读写分离实战（一个注解搞定读写分离 && 强制路由主库）
28. MQ专题-MQ典型的使用场景
29. MQ专题-如何确保消息的可靠性
30. MQ专题-SpringBoot中，手把手教你实现事务消息
31. 手写一个好用的延迟任务处理工具类
32. MQ专题-MQ延迟消息通用方案实战
33. MQ消息幂等消费 & 消费失败衰减式重试通用方案 & 代码 & 文档
34. MQ专题：顺序消息通用方案实战 & 代码落地 & 文档
35. MQ专题：消息积压相关问题及解决思路
36. 分布式事务-MQ最终一致性-实现跨库转账（案例+源码+文档）
37. 分布式事务-MQ最终一致性-实现电商账户余额提现到微信钱包（案例+源码+文档）
38. 分布式事务：通用的TCC分布式事务生产级代码落地实战
39. 分布式锁详解
40. 分享一个特别好用的Redissson分布式锁工具类
41. 一个注解轻松搞定分布式锁
42. 微服务中如何传递公共参数？
43. 接口幂等，通用方案 & 代码落地
44. 微服务链路日志追踪实战
45. 接口测试利器HTTP Client，不用Postman也可以
46. 封装MyBatis，实现通用无SQL版CRUD功能ORM框架
47. MyBatisPlus 轻松实现多租户数据隔离
48. 电商系统-资金账户表设计 及 应用实战
49. UML画图神器：PlantUML，画图效率飞升
50. 多线程事务，3秒插入百万数据
51. SpringBoot中自动初始化数据库功能，非常好用
52. SpringBoot优雅停机
53. 分享一个特好用的集合工具类，开发效率轻松翻倍
54. 性能调优：线程死锁相关问题
```



## 课程部分大纲，连载中。。。。

以下课程均来源于个人多年的实战，均提供原理讲解 && 源码落地

1. 分片上传实战
2. 通用并发处理工具类实战
3. 实现一个好用接口性能压测工具类
4. 超卖问题的4种解决方案，也是防止并发修改数据出错的通用方案
5. Semaphore实现接口限流实战
6. 并行查询，优化接口响应速度实战
7. 接口性能优化之大事务优化
8. 通用的Excel动态导出功能实战
9. 手写线程池管理器，管理&监控所有线程池
10. 动态线程池
11. SpringBoot实现动态Job实战
12. 并行查询，性能优化利器，可能有坑
13. 幂等的4种解决方案，吃透幂等性问题
14. 接口通用返回值设计与实现
15. 接口太多，各种dto、vo不计其数，如何命名？
16. 一个业务太复杂了，方法太多，如何传参？
17. 接口报错，如何快速定位日志？
18. 线程数据共享必学的3个工具类：ThreadLocal、InheritableThreadLocal、TransmittableThreadLocal
19. 通过AOP统一打印请求链路日志，排错效率飞升
20. 大批量任务处理常见的方案（模拟余额宝发放收益）
21. 并发环境下，如何验证代码是否正常？
22. MySql和Redis数据一致性
23. SpringBoot数据脱敏优雅设计与实现
24. 一行代码搞定系统操作日志
25. Aop简化MyBatis分页功能
26. ThreadLocal 遇到线程池有大坑 & 通用解决方案
27. SpringBoot读写分离实战（一个注解搞定读写分离 && 强制路由主库）
28. MQ专题：MQ典型的7种使用场景
29. MQ专题：如何确保消息的可靠性
30. MQ专题：SpringBoot中，手把手教你实现事务消息
31. 手写一个好用的延迟任务处理工具类
32. MQ专题：延迟消息通用方案实战
33. MQ专题：消息幂等消费 & 消费失败自动重试通用方案 & 代码落地
34. MQ专题：顺序消息通用方案实战
35. MQ专题：消息积压问题
36. 分布式事务-MQ最终一致性-实现跨库转账（案例+源码+文档）
37. 分布式事务-MQ最终一致性-实现电商账户余额提现到微信钱包（案例+源码+文档）
38. 分布式事务：通用的TCC分布式事务生产级代码落地实战
39. 分布式锁详解
40. 分享一个特别好用的Redissson分布式锁工具类
41. 分布式锁：一个注解轻松实现布式锁
42. 微服务中如何传递上下文？实战
43. 接口幂等，通用方案 & 代码落地
44. 微服务链路日志追踪实战
45. 接口测试利器HTTP Client，不用Postman也可以
46. 封装MyBatis，实现通用无SQL版CRUD功能
47. MyBatisPlus 轻松实现 多租户数据隔离
48. 电商系统-资金账户表设计 及 应用实战
49. 开发者必须掌握的一款UML画图工具，画图效率飞升
50. 多线程事务，3秒插入百万数据
51. SpringBoot自动初始化数据库功能，太好用了
52. SpringBoot优雅停机
53. 分享一个特别好用的集合工具类，开发效率大幅提升
54. 性能调优：如何排查死锁？
55. 性能调优：OOM如何排查？
56. 性能调优：CPU被打满，如何排查？
57. 性能调优：生产代码没生效，如何定位？
58. 性能调优：接口太慢，如何定位？
59. 性能调优：如何查看生产上接口的入参和返回值？
60. 性能调优：远程debug
61. 生产上出现了各种故障，如何定位？
62. db和缓存一致性，常见的方案
63. Redis场景案例。。。
64. 系统资金账户设计案例（一些系统涉及到资金操作）
65. 工作中常见的场景案例设计与实现。。。