1. 背景
在
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | "MySQL Statement Cancellation Timer" #20647 daemon prio=5 os_prio=0 tid=0x00007f2d087e9800 nid=0xfb83 in Object.wait() [0x00007f2b4b45a000] java.lang.Thread.State: TIMED_WAITING (on object monitor) at java.lang.Object.wait(Native Method) at java.util.TimerThread.mainLoop(Timer.java:552) - locked <0x00000005da147038> (a java.util.TaskQueue) at java.util.TimerThread.run(Timer.java:505) Locked ownable synchronizers: - None "MySQL Statement Cancellation Timer" #24138 daemon prio=5 os_prio=0 tid=0x00007f402802c800 nid=0x4cf64 in Object.wait() [0x00007f3e49453000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) at java.lang.Object.wait(Object.java:502) at java.util.TimerThread.mainLoop(Timer.java:526) - locked <0x00000005f606cc60> (a java.util.TaskQueue) at java.util.TimerThread.run(Timer.java:505) Locked ownable synchronizers: - None |
2. TimerThread

- 根据定位
Timer.java:526 位置的代码, 当前状态WAITING (on object monitor) , 表示当前的timer 线程池为空, 正在等待新入驻; - 根据定位
Timer.java:552 位置的代码, 当前状态TIMED_WAITING (on object monitor) 表示任务等待被激活;

3. getCancelTimer
根据线程名称

4. getCancelTimer 的上游调用
主要是


5. 创建 CancelTask timeoutTask
在

然后在项目的

6. CancelTask 执行过程
在

在

7. Connection 关闭时
在

8. 总结 MySQL Statement Cancellation Timer 线程的流程

- 设置了
queryTimeout 会使jdbc driver 在每次查询数据库时新建CancelTask (timeoutTask 对象) 线程来处理超时, 并使用CancelTimer (在ConnectionImpl 类中) 来进行调度; - 如果
SQL 查询超时了, 则会在timeoutTask 的run 方法里调用com.mysql.jdbc.ConnectionImpl#realClose 来释放CancelTimer ; - 如果
Connection 正常关闭close 时, 也会调用com.mysql.jdbc.ConnectionImpl#realClose 来释放CancelTimer ;
9. 阅读资料
- 一次数据库连接池优化的实践剖析
- MySQL Statement Cancellation Timer问题