温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

什么是线程死锁

发布时间:2021-10-14 11:03:58 来源:亿速云 阅读:102 作者:iii 栏目:编程语言

本篇内容介绍了“什么是线程死锁”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

死锁定义
死锁产生的条件
死锁示例
如何避免死锁

1. 死锁定义

● 死锁是指两个或两个以上的线程在执行过程中,因争夺资源而造成互相等待的现象,
在无外力作用的情况下,这些线程会一直相互等待而无法继续运行下去

2. 死锁产生的条件

● 互斥条件:指线程对已经获取到的资源进行排它性使用,即该资源同时只由一个线程占用。
如果此时还有其他线程请求获取该资源,则请求者只能等待,直至占有资源的线程释放该资源。
● 请求并持有条件:指一个线程已经持有了至少一个资源,但又提出了新的资源请求,而新资源已被其他线程占有,
所以当前线程会被阻塞,但阻塞的同时并不释放自己已经获取的资源。
● 不可剥夺条件:指线程获取到的资源在自己使用完之前不能被其他线程抢占,只有在自己使用完毕后才由自己释放该资源。
● 环路等待条件:指在发生死锁时,必然存在一个线程—资源的环形链,即线程集合{T0, T1, T2, …, Tn}中的T0正在
等待一个T1占用的资源,T1正在等待T2占用的资源,……Tn正在等待已被T0占用的资源。

3. 死锁示例

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();
    }
}

什么是线程死锁

4. 死锁的避免

● 加锁顺序:线程按照相同的顺序加锁。
● 加锁时限,线程获取锁的过程中限制一定的时间,如果给定时间内获取不到,就算了,别勉强自己。这需要用到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日志,你会发现以下结果: 什么是线程死锁

“什么是线程死锁”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI