前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >什么是死锁?(把死锁给大家讲明白,知道是什么,为什么用,怎么用)

什么是死锁?(把死锁给大家讲明白,知道是什么,为什么用,怎么用)

作者头像
默 语
发布2024-11-20 08:58:30
发布2024-11-20 08:58:30
15100
代码可运行
举报
文章被收录于专栏:JAVAJAVA
运行总次数:0
代码可运行

3个方面回答 :

1.死锁是什么?

提供了几种理解的方式帮助大家更好的理解;如有疑问可提出;

死锁是一组相互竞争资源的线程因为他们之间得到互相等待导致“永久“阻塞的现象; (你等我 我等你 你不放我也不放 就导致“永久“阻塞的现象)

死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程

了解了说你是死锁后我们要知道为什么会发生死锁呢,请看下面;

2.发生死锁的原因?

分为下面4钟原因

互斥条件

共享资源 X y 只能被一个线程占有

占用且等待

线程T1占用的共享资源X 他在等待共享Y的时候帮不释放自己的X

不可抢占

其他线程不能去抢占t1线程占有的资源

循环等待

线程t1 等t2 占有的资源,线程t2 等t1占有的资源 循环等等

3.如何避免死锁?

打破死锁的原因即可避免

互斥条件

无法破坏的因为锁本身就是通过互斥解决线程的安全的问题

占用且等待

一次性申请所有的资源就不会存在等待了

不可抢占

占用部分资源的线程,进一步申请其他的资源的时候如果申请不到可以主动释放他占有的资源,这样就破坏了不可抢占

循环等待

按照顺序申请资源进行预防,所谓按序申请是指资源是有线性顺序的,申请的时候可以先申请资源序号小的 在申请资源序号大的 ,这样线性化循环就不存在等待了

下面我们用代码理解下死锁:

代码语言:javascript
代码运行次数:0
运行
复制
package com.example;

public class Deadlock {

       public static String str1 = "str1";
        public static String str2 = "str2";

        public static void main(String[] args){
            Thread a = new Thread(() -> {
                try{
                    while(true){
                        synchronized(Deadlock.str1){
                            System.out.println(Thread.currentThread().getName()+"锁住 str1");
                            Thread.sleep(1000);
                            synchronized(Deadlock.str2){
                                System.out.println(Thread.currentThread().getName()+"锁住 str2");
                            }
                        }
                    }
                }catch(Exception e){
                    e.printStackTrace();
                }
            });

            Thread b = new Thread(() -> {
                try{
                    while(true){
                        synchronized(Deadlock.str2){
                            System.out.println(Thread.currentThread().getName()+"锁住 str2");
                            Thread.sleep(1000);
                            synchronized(Deadlock.str1){
                                System.out.println(Thread.currentThread().getName()+"锁住 str1");
                            }
                        }
                    }
                }catch(Exception e){
                    e.printStackTrace();
                }
            });

            a.start();
            b.start();
        }
    }

上面的代码就是一个完整的死锁程序,程序中有两个线程,线程1锁住了str1,获得锁之后休眠1秒钟,这个时候线程2锁住了str2,也进行休眠操作。 线程1休眠完了之后去锁str2,但是str2已经被线程2给锁住了,这边只能等待,同样的道理,线程2休眠完之后也要去锁str1,同样也会等待,这样死锁就产生了。

将下面这2行代码的值改成一样,就不会存在了

代码语言:javascript
代码运行次数:0
运行
复制
public static String str1 = "str1";
public static String str2 = "str1";

在声明一个对象作为锁的时候要注意字符串类型锁对象,因为字符串有一个常量池,如果不同的线程持有的锁是具有相同字符的字符串锁时,两个锁实际上同一个锁。

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.死锁是什么?
  • 2.发生死锁的原因?
  • 3.如何避免死锁?
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档