前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >线程死锁是什么

线程死锁是什么

作者头像
全栈程序员站长
发布2022-09-14 09:46:37
2390
发布2022-09-14 09:46:37
举报
文章被收录于专栏:全栈程序员必看

大家好,又见面了,我是你们的朋友全栈君。

线程死锁:

两个或两个以上的线程在执行过程中同时被阻塞,它们中的某个或者全部都在等待某个资源被释放,由于线程被无限期的阻塞,系统处于死锁状态或系统产生了死锁,这些永远在互相等待的线程被称为线程死锁

线程死锁是什么
线程死锁是什么

线程死锁的演示

如上图所示,线程A持有资源2,线程B持有资源1,它们都想申请对方的资源,所以这两个线程就会互相等待而进入死锁状态

如果想要了解什么是线程阻塞的朋友,可以看我之前发的一篇线程的阻塞

线程死锁示例代码如下:

代码语言:javascript
复制
public class Demo {

    private static Object resource1 = new Object();    //资源 1
    private static Object resource2 = new Object();    //资源 2

    public static void main(String[] args) {
        new Thread(() -> {
            synchronized (resource1) {
                System.out.println(Thread.currentThread() + "get resource1");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread() + "waiting get resource2");
                synchronized (resource2) {
                    System.out.println(Thread.currentThread() + "get resource2");
                }
            }
        }, "线程 1").start();
        new Thread(() -> {
            synchronized (resource2) {
                System.out.println(Thread.currentThread() + "get resource2");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread() + "waiting get resource1");
                synchronized (resource1) {
                    System.out.println(Thread.currentThread() + "get resource1");
                }
            }
        }, "线程 2").start();
    }
}

输出结果:
Thread[线程 1,5,main]get resource1
Thread[线程 2,5,main]get resource2
Thread[线程 1,5,main]waiting get resource2
Thread[线程 2,5,main]waiting get resource1

线程 A 通过 synchronized (resource1) 获得 resource1 的监视器锁,然后通过Thread.sleep(1000);让线程 A 休眠 1s 为的是让线程 B 得到CPU执行权,然后获取到 resource2 的监视器锁。线程 A 和线程 B 休眠结束了都开始企图请求获取对方的资源,然后这两个线程就会陷入互相等待的状态,这也就产生了死锁

不了解synchronized的友友们,可以翻我之前的一篇关于synchronized

形成死锁的四个必要条件:

  1. 互斥条件:线程(进程)对于所分配到的资源具有排它性,即一个资源只能被一个线程(进程)占用,直到被该线程(进程)释放
  2. 请求与保持条件:一个线程(进程)因请求资源而被阻塞时,对以获得的资源保持不放
  3. 不剥夺条件:线程(进程)已获得的资源在未使用完之前不能被其他线程强行剥夺,只有自己使用完毕后才释放资源
  4. 循环等待条件:当发生死锁时,所等待的线程(进程)必定会形成一个环路(类似于死循环),造成永久阻塞

实际应用中,为了避免线程死锁,必须打破其中一个条件:

  • 互斥条件没有办法破坏,因为我们用锁本来就是想让它们互斥的(临界资源需要互斥访问)
  • 破坏请求与保持条件,一次性申请所有资源
  • 破坏不剥夺条件,占用部分资源的线程进一步申请其他资源时,如果申请不到,可以主动释放该线程占有的资源
  • 破坏循环等待条件,按某一顺序申请资源来预防死锁,释放资源则按此顺序的反序来释放

大家有不理解可以翻我博客哦!

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/158542.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年7月1,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档