本篇内容介绍了“什么是线程死锁”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
死锁定义 死锁产生的条件 死锁示例 如何避免死锁
● 死锁是指两个或两个以上的线程在执行过程中,因争夺资源而造成互相等待的现象, 在无外力作用的情况下,这些线程会一直相互等待而无法继续运行下去
● 互斥条件:指线程对已经获取到的资源进行排它性使用,即该资源同时只由一个线程占用。 如果此时还有其他线程请求获取该资源,则请求者只能等待,直至占有资源的线程释放该资源。 ● 请求并持有条件:指一个线程已经持有了至少一个资源,但又提出了新的资源请求,而新资源已被其他线程占有, 所以当前线程会被阻塞,但阻塞的同时并不释放自己已经获取的资源。 ● 不可剥夺条件:指线程获取到的资源在自己使用完之前不能被其他线程抢占,只有在自己使用完毕后才由自己释放该资源。 ● 环路等待条件:指在发生死锁时,必然存在一个线程—资源的环形链,即线程集合{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日志,你会发现以下结果:
“什么是线程死锁”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
原文链接:https://my.oschina.net/u/1156250/blog/5016367