本篇内容介绍了“什么是线程死锁”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
死锁定义 死锁产生的条件 死锁示例 如何避免死锁
● 死锁是指两个或两个以上的线程在执行过程中,因争夺资源而造成互相等待的现象, 在无外力作用的情况下,这些线程会一直相互等待而无法继续运行下去
● 互斥条件:指线程对已经获取到的资源进行排它性使用,即该资源同时只由一个线程占用。 如果此时还有其他线程请求获取该资源,则请求者只能等待,直至占有资源的线程释放该资源。 ● 请求并持有条件:指一个线程已经持有了至少一个资源,但又提出了新的资源请求,而新资源已被其他线程占有, 所以当前线程会被阻塞,但阻塞的同时并不释放自己已经获取的资源。 ● 不可剥夺条件:指线程获取到的资源在自己使用完之前不能被其他线程抢占,只有在自己使用完毕后才由自己释放该资源。 ● 环路等待条件:指在发生死锁时,必然存在一个线程—资源的环形链,即线程集合{T0, T1, T2, …, Tn}中的T0正在 等待一个T1占用的资源,T1正在等待T2占用的资源,……Tn正在等待已被T0占用的资源。
package com.pimee.thread.deadlock; /** * 线程死锁示例 */ public class DeadLock { private static Object resourceA = new Object(); private static Object resourceB = new Object(); public static void main(String[] args) { Thread threadA = new Thread(new Runnable() { [@Override](https://my.oschina.net/u/1162528) public void run() { synchronized (resourceA){ System.out.println(Thread.currentThread().getName() + "get resourceA"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " is waiting for resourceB"); synchronized (resourceB){ System.out.println(Thread.currentThread().getName() + " get resourceB"); } } } }); Thread threadB = new Thread(new Runnable() { [@Override](https://my.oschina.net/u/1162528) public void run() { synchronized (resourceB){ System.out.println(Thread.currentThread().getName() + " get resourceB"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " is waiting for resourceA"); synchronized (resourceA){ System.out.println(Thread.currentThread().getName() + " get resourceA"); } } } }); threadA.start(); threadB.start(); } }
● 加锁顺序:线程按照相同的顺序加锁。 ● 加锁时限,线程获取锁的过程中限制一定的时间,如果给定时间内获取不到,就算了,别勉强自己。这需要用到Lock的一些API
上面死锁的demo,修改一下加锁的书序,可以解决问题
package com.pimee.thread.deadlock; /** * 线程死锁示例 */ public class DeadLock { private static Object resourceA = new Object(); private static Object resourceB = new Object(); public static void main(String[] args) { Thread threadA = new Thread(new Runnable() { @Override public void run() { synchronized (resourceA){ System.out.println(Thread.currentThread().getName() + " get resourceA"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " is waiting for resourceB"); synchronized (resourceB){ System.out.println(Thread.currentThread().getName() + " get resourceB"); } } } }); Thread threadB = new Thread(new Runnable() { @Override public void run() { synchronized (resourceA){ System.out.println(Thread.currentThread().getName() + " get resourceA"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " is waiting for resourceA"); synchronized (resourceB){ System.out.println(Thread.currentThread().getName() + " get resourceB"); } } } }); threadA.start(); threadB.start(); } }
可以使用jstatck查看jvm日志,你会发现以下结果:
“什么是线程死锁”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。