Java多线程(五):死锁
2019-07-08 17:48
1771 查看
死锁
概念
当线程Thread-0持有锁Lock1,Thread-1持有锁Lock2,此时Thread-0申请Lock2锁的使用权,Thread-1申请Lock1锁的使用权,Thread-0和Thread-1都在无限地等待锁的使用权。这样就造成了死锁。
死锁是主要由于设计的问题。一旦出现死锁,死锁的线程就会永远不能使用,同步方法不会被执行,死锁线程不会被自动终止,无尽地消耗CPU资源。
例子
看一个例子
ThreadDomain29类,模拟图片中,线程持有一个锁,申请被其他线程持有的锁的情况
public class ThreadDomain29 { private final Object obj1 = new Object(); private final Object obj2 = new Object(); public void obj1obj2() throws Exception { synchronized (obj1) { Thread.sleep(2000); synchronized (obj2) { System.out.println("obj1obj2 end!"); } } } public void obj2obj1() throws Exception { synchronized (obj2) { Thread.sleep(2000); synchronized (obj1) { System.out.println("obj2obj1 end!"); } } } }
MyThread29_0类
public class MyThread29_0 extends Thread{ private ThreadDomain29 dl; public MyThread29_0(ThreadDomain29 dl) { this.dl = dl; } public void run() { try { dl.obj1obj2(); } catch (Exception e) { e.printStackTrace(); } } }
MyThread29_1类
public class MyThread29_1 extends Thread{ private ThreadDomain29 dl; public MyThread29_1(ThreadDomain29 dl) { this.dl = dl; } public void run() { try { dl.obj2obj1(); } catch (Exception e) { e.printStackTrace(); } } }
main方法
public class MyThread29_main { public static void main(String[] args) { ThreadDomain29 dl = new ThreadDomain29(); MyThread29_0 t0 = new MyThread29_0(dl); MyThread29_1 t1 = new MyThread29_1(dl); t0.start(); t1.start(); while(true); } }
因为发生了死锁,所以你不会看到任何结果。
死锁排查
jps+jstack
jps找到进程id
jstack打印堆栈
输入jstack 10208
可以看到,找到了两个死锁。
JConsole
命令行输入JConsole
点击“检测死锁”
已经检测到了死锁
Java Visual VM
命令行输入jvisualvm
找到我们的进程
自动检测到死锁,推荐使用这种方式
死锁避免
1.尽量少用嵌套的锁。
2.如果一定要用嵌套锁,那么请规定好获取锁的顺序。例子如下:
//伪代码 //condition1可以是属性值大小,hash值大小的比较等等 if(condition1){ synchronized (obj2) { Thread.sleep(2000); synchronized (obj1) { System.out.println("obj2obj1 end!"); } } }else{ synchronized (obj1) { Thread.sleep(2000); synchronized (obj2) { System.out.println("obj1obj2 end!"); } } }
3.使用Lock的tryLock方法,它表示用来尝试获取锁,如果获取成功,则返回true,如果获取失败(即锁已被其他线程获取),则返回false,这个方法无论如何都会立即返回。在拿不到锁时不会一直在那等待。
后面讲到ReentrantLock会详细分析。
相关文章推荐
- java多线程:并发协作-死锁
- java多线程如何避免死锁
- JAVA多线程——死锁分析
- 17、Java并发性和多线程-避免死锁
- Java多线程:死锁
- JAVA多线程(二)竞态条件、死锁及同步机制
- java 多线程 解决死锁
- java面试题---请用多线程写死锁
- Java多线程中活锁和死锁有什么区别?
- java多线程之死锁
- Java多线程(十六):死锁
- java例程练习(多线程[死锁问题])
- Java 多线程 同步与死锁
- Java多线程探究-死锁原因
- java多线程中的死锁
- Java基础之多线程(一)--概述、同步、死锁、单例模式
- 黑马程序员-JAVA基础-多线程的安全、同步与死锁
- java多线程死锁例子
- java多线程学习之死锁的模拟和避免
- Java多线程死锁的例子