如何防止死锁
- tryLock
- 按经历只获取一个资源,不要同时获取多个资源
- 尽量按顺序上锁
总结:
- tryLock 方法
- lock方法
lock是无条件阻塞加锁,tryLock 的话是 可以被打断的,被中断的
用 tryLock 可以实现一个自旋锁
1
2
3
|
while(!reentrantLock.tryLock()) {
do_Something();
}
|
如何查看线程死锁
- 用 jstack 命令进行查看, jstack 命令会显示死锁的线程
- 两个线程操作数据库,数据库死锁的问题
任务管理器 找到 java.exe 几个进程的 PID ,一个个去试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
jstack 20520 | BLOCKED
:<<EOF
jstack 20520 | findstr BLOCKED
java.lang.Thread.State: BLOCKED (on object monitor)
java.lang.Thread.State: BLOCKED (on object monitor)
EOF
# 这里我是 windows 环境,linux 用 grep
jstack 20520 | findstr deadlock
:<<EOF
Found one Java-level deadlock:
Found 1 deadlock.
EOF
:<<EOF
Found one Java-level deadlock:
=============================
"Thread2":
waiting to lock monitor 0x00000000215e35c8 (object 0x00000007404ebfc8, a java.lang.String),
which is held by "Thread1"
"Thread1":
waiting to lock monitor 0x00000000235a3158 (object 0x00000007404ec000, a java.lang.String),
which is held by "Thread2"
Java stack information for the threads listed above:
===================================================
"Thread2":
at Main$DeadLockSample.run(Main.java:38)
- waiting to lock <0x00000007404ebfc8> (a java.lang.String)
- locked <0x00000007404ec000> (a java.lang.String)
"Thread1":
at Main$DeadLockSample.run(Main.java:38)
- waiting to lock <0x00000007404ec000> (a java.lang.String)
- locked <0x00000007404ebfc8> (a java.lang.String)
EOF
|
查看数据库死锁
1
2
3
4
5
6
7
8
|
# 查看是否锁表
show open tables where in_use > 0
show processlist;
# 查看进程
select * from information_schema.INNODB_LOCKS;
# 查看等待锁的事务
select * from information_schema.INNODB_LOCK_WAITS;
|
线程之间如何进行通讯
- 线程之间可以通过共享内存 或基于网络进行通讯
- 如果通过共享内存通讯,就要考虑并发问题,什么时候阻塞
- 像 java中的 wait,notify 就是阻塞和唤醒
- 通过网络就比较简单了, 网络连接发送数据给对方 【也要考虑并发加锁问题】