程序死锁的原因
-
交叉锁原因可导致程序出现死锁
线程A持有R1的锁等待线程B的R2的锁,线程A持有R1的锁,线程B持有R2的锁,大家互相等待,死锁; -
内存不足
当并发系统请求可用内存,如果此时系统内存不足,则可能会出现死锁情况,两个线程T1和T2,执行某个任务,其中T1已经获取10MB内存,T2获取了20MB内存,如果每个线程的执行单元都需要30MB的内存,但是剩余的内存刚好为20MB,那么两个线程有可能在等待彼此能释放内存资源。 -
一问一答的数据交换
服务端开启某个端口,等待客户端访问,客户端发送请求立即等待接收,由于服务端某种原因错过丢失了请求,陷入了互相等待过程。 -
数据库锁
无论是数据表级别,还是行级别的锁,比如某个线程执行for update 退出的事物 其他访问数据库时都将陷入死锁 -
文件锁
同理 某线程获得文件所意外所意外退出,其他读取文件线程也会进入死锁,直到释放文件句柄资源 -
死循环引起的死锁
死循环获得锁
程序死锁举例
本节中,我们将举例由于交叉锁引起死锁的情况,交叉锁不仅是自己代码有可能有问题,还有一些开源框架api 不熟悉导致死锁情况出现,前者比后者排查简单得多,所以开发过程中熟悉api很有必要。
package thread.deadlock;
public class Demo {
private final Object read_lock=new Object();
private final Object write_lock=new Object();
public void read(){
synchronized (read_lock){
System.out.println("I will read,and this read_lock will belong me ");
synchronized (write_lock){
System.out.println("I will write,and those locks are all mine hhhhha");
System.out.println(Thread.currentThread().getName()+"heiehiehie");
}
System.out.println("I lost wrote_lock yingying ");
}
System.out.println("i lost all");
}
public void write(){
synchronized (write_lock){
System.out.println("I will write,and those locks are all mine hhhhha");
synchronized (read_lock){
System.out.println(Thread.currentThread().getName()+"是我");
}
System.out.println("I lost wrote_lock yingying ");
}
System.out.println("i lost all");
}
public static void main(String[] args) {
final Demo demo = new Demo();
new Thread(()->{
while (true){
demo.read();
}
},"read Thread\t").start();
new Thread(()->{
while (true){
demo.write();
}
},"write Thread \t").start();
}
}
运行结果
I will read,and this read_lock will belong me
I will write,and those locks are all mine hhhhha
read Thread heiehiehie
I lost wrote_lock yingying
i lost all
I will read,and this read_lock will belong me
I will write,and those locks are all mine hhhhha
read Thread heiehiehie
I lost wrote_lock yingying
i lost all
I will read,and this read_lock will belong me
I will write,and those locks are all mine hhhhha
read Thread heiehiehie
I lost wrote_lock yingying
i lost all
I will read,and this read_lock will belong me
I will write,and those locks are all mine hhhhha
read Thread heiehiehie
I lost wrote_lock yingying
i lost all
I will read,and this read_lock will belong me
I will write,and those locks are all mine hhhhha
read Thread heiehiehie
I lost wrote_lock yingying
i lost all
I will read,and this read_lock will belong me
I will write,and those locks are all mine hhhhha
read Thread heiehiehie
I lost wrote_lock yingying
i lost all
I will read,and this read_lock will belong me
I will write,and those locks are all mine hhhhha
read Thread heiehiehie
I lost wrote_lock yingying
i lost all
I will read,and this read_lock will belong me
I will write,and those locks are all mine hhhhha
read Thread heiehiehie
I lost wrote_lock yingying
i lost all
I will read,and this read_lock will belong me
I will write,and those locks are all mine hhhhha
read Thread heiehiehie
I lost wrote_lock yingying
i lost all
I will read,and this read_lock will belong me
I will write,and those locks are all mine hhhhha
read Thread heiehiehie
I lost wrote_lock yingying
i lost all
I will read,and this read_lock will belong me
I will write,and those locks are all mine hhhhha
read Thread heiehiehie
I lost wrote_lock yingying
i lost all
I will read,and this read_lock will belong me
I will write,and those locks are all mine hhhhha
read Thread heiehiehie
I lost wrote_lock yingying
i lost all
I will read,and this read_lock will belong me
I will write,and those locks are all mine hhhhha
结果明显不过,程序直接死锁 不在运行,
那么我们怎么诊断他呢 这里笔者使用的是jconsole
按步骤操作即可 这时候我们可以看到线程锁持有者是交互的
好了今天就先到这里了