死锁

参考博文:
https://blog.csdn.net/hd12370/article/details/82814348

死锁是什么?

死锁是指多个线程在运行过程中,因为抢占资源而造成一种僵局。
比如:当线程A持有独占锁a,并尝试获取独占锁b的同时,线程B持有独占锁b,并尝试获取独占锁a的情况下,就会发生AB线程由于持有对方需要的锁,而发生阻塞,我们称为死锁。

例如:

class Program
    {
        static void Main(string[] args) {
            DeadLockDemo deadLockDemo = new DeadLockDemo();
            deadLockDemo.Test();
            Console.ReadKey();
        }
    }
    class DeadLockDemo
    {
        private readonly object locker1 = new object();
        private readonly object locker2 = new object();
        public void Test() {
            Thread th1 = new Thread(Method1);
            Thread th2 = new Thread(Method2);
            th1.Start();
            th2.Start();
        }
        void Method1() {
            lock (locker1) {
                try {
                    Thread.Sleep(10000);

                } catch (Exception e) {
                    Console.WriteLine(e.StackTrace);
                }
                Console.WriteLine("线程a尝试获取locker2");
                lock (locker2) {
                    Console.WriteLine("线程a已经获取locker2");
                }
            }
        }
        void Method2() {
            lock (locker2) {
                try {
                    Thread.Sleep(10000);

                } catch (Exception e) {
                    Console.WriteLine(e.StackTrace);
                }
                Console.WriteLine("线程b尝试获取locker1");
                lock (locker1) {
                    Console.WriteLine("线程b已经获取locker1");
                }
            }
        }
    }

在这里插入图片描述
线程b尝试获取String.class
线程a尝试获取integer.class



.
无限阻塞下去

在上面的例子中,由于已经不存在 线程a 持有 线程b需要的锁,而线程b持有线程a需要的锁的逻辑了,所以Demo顺利执行完毕。

死锁产生的原因?

互斥性:一个资源每次只能被一个线程使用
请求和保持条件:当进程因请求资源而阻塞s时,对已获得的资源保持不放
不剥夺原则:进程已获得的资源在未使用完之前,不能剥夺,只能在使用完后自己释放
循环等待条件:若干线程之间形成一种头尾相接的循环等待资源关系

如何避免死锁?

资源一次性分配:一次性分配资源
只要一个资源得不到分配,也不给这个进程分配资源
可剥夺资源:即当某进程获得了部分资源,得不到其他资源,则释放已占有的资源
资源有序分分配:系统给每类资源赋予一个编号,每一个进程按标号递增的顺序请求资源,释放则相反。

上例死锁代码可以改为:

 class Program {
        static void Main(string[] args) {
            DeadLockDemo deadLockDemo = new DeadLockDemo();
            deadLockDemo.Test();
            Console.ReadKey();
        }
    }
    class DeadLockDemo
    {
        private readonly object locker1 = new object();
        private readonly object locker2 = new object();
        public void Test() {
            Thread th1 = new Thread(Method1);
            Thread th2= new Thread(Method2);
            th1.Start();
            th2.Start();
        }
         void Method1() {
            lock (locker1) {
                try {
                    Thread.Sleep(10000);

                } catch (Exception e) {
                    Console.WriteLine(e.StackTrace);
                }
                Console.WriteLine("线程a尝试获取locker2");
                lock (locker2) {
                    Console.WriteLine("线程a已经获取locker2");
                }
            }
        }
        void Method2() {
            lock (locker1) {
                try {
                    Thread.Sleep(10000);

                } catch (Exception e) {
                    Console.WriteLine(e.StackTrace);
                }
                Console.WriteLine("线程b尝试获取locker2");
                lock (locker2) {
                    Console.WriteLine("线程b已经获取locker2");
                }
            }
        }
    }

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值