死锁的产生

  死锁,顾名思义就是由于加锁所导致的死循环(也就是程序由于加锁操作而僵住了)

   public static void main(String[] args) throws InterruptedException {
        Object locker1 = new Object();
        Object locker2 = new Object();

        Thread t1 = new Thread(()->{
           synchronized (locker1)
           {
               try {
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
               synchronized (locker2)
               {
                   System.out.println(Thread.currentThread().getName()+"获取了两把锁");
               }
           }

        },"t1");
        Thread t2 = new Thread(()->{
           synchronized (locker2)
           {
               try {
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
               synchronized (locker1)
               {
                   System.out.println(Thread.currentThread().getName()+"获取了两把锁");
               }
           }

        },"t2");

        t1.start();
        t2.start();

        t1.join();
        t2.join();
    }

最经典的哲学家吃面问题:

这个例子,哲学家相当于线程,然后筷子相当于锁,由于哲学家互相抢对方的筷子,所以没人能够吃面 

JVM在对对象加锁之前,会先验证当前对象是否已经被加锁,如果别加锁就不会进行二次加锁,这样就有效避免产生死锁~

死锁产生的四个必备条件(缺一不可):

1、锁是不可抢占的(一但被持有,其他的线程不能够再次进行获取,要么等待锁释放,要么放弃获取)

2、锁是互斥的(即锁和拿锁的对象是一对一,多个对象获取锁需要阻塞等待)

3、在已经获取一把锁的情况下,尝试获取另外一把锁,拿不到锁就阻塞等待

4、在获取锁的过程中,如果没拿到锁会产生循环等待(拿不到一直等)

那么怎么破坏死锁?

当我们在对自己的代码块进行加锁时,对于锁的模拟实现,我们可以自行控制锁的特性(自行实现,例如规定锁可以给多个线程持有,锁不具备互斥性等..) 

①规定线程获取锁的顺序

 ②规定线程的阻塞等待方式(在遇到锁被占有的情况下,线程不硬等锁释放或者直接跳过阻塞等待)

 综上所述,只要破坏四个必备的条件之一,就能避免产生死锁,而在平时使用锁的时候尽量避免写嵌套锁(嵌套锁在java中有JVM进行处理,会避免对象进行二次加锁,但是如果在c++中写嵌套锁那就会僵住),这样才能避免产生死锁~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值