Java死锁

标签: Java 线程 死锁
3人阅读 评论(0) 收藏 举报
分类:

一、死锁是什么

死锁:当两个线程相互等待对方释放同步监视器便会发生死锁。

死锁产生的4个必要条件:

1.互斥条件:一个资源每次只能被一个线程使用。

2.请求与保持条件:一个线程因请求资源而阻塞时,对已获得的资源保持不放。

3.不剥夺条件:线程已获得的资源在未使用完之前,不得强行剥夺。

4.循环等待条件:若干线程之间形成头尾相接的循环等待资源关系。

二、如何避免死锁

避免死锁的方法是允许前3个条件存在,破坏第4个条件。

三、产生死锁的程序

public class A {
    public synchronized void bar(B b) {
        System.out.println("当前线程:" + Thread.currentThread().getName() + "进入到A实例的bar()方法");
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("当前线程:" + Thread.currentThread().getName() + "准备执行B实例的last()方法");
        b.last();
    }
    public synchronized void last() {
        System.out.println("进入到A的同步方法last()");
    }
}
public class B {
    public synchronized void foo(A a) {
        System.out.println("当前线程:" + Thread.currentThread().getName() + "进入到B实例的foo()方法");
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("当前线程:" + Thread.currentThread().getName() + "准备执行A实例的last()方法");
        a.last();
    }
    public synchronized void last() {
        System.out.println("进入到B的同步方法last()");
    }
}
public class Deadlock implements Runnable{
    A a = new A();
    B b = new B();
    public void init() {
        Thread.currentThread().setName("主线程");
        b.foo(a);
    }
    public void run() {
        Thread.currentThread().setName("副线程");
        a.bar(b);
    }

    public static void main(String[] args) {
        Deadlock deadlock = new Deadlock();
        new Thread(deadlock).start();
        deadlock.init();
    }
}

其中,运行Deadlock的main方法结果如下:

当前线程:主线程进入到B实例的foo()方法
当前线程:副线程进入到A实例的bar()方法
当前线程:主线程准备执行A实例的last()方法
当前线程:副线程准备执行B实例的last()方法

分析:

Deadlock执行时,一共有2个线程在运行,其中主线程进入到B实例的foo()方法,获得了B对象的锁,进入休眠阶段;此时副线程获取CPU运行资源,副线程进入到A实例的bar()方法,获得了A对象的锁,进入休眠阶段;然后主线程准备执行A实例的last方法,但由于A对象的锁此时被副线程占有,主线程被阻塞,等待A对象的锁被副线程释放;此时副线程准备执行B实例的last方法,但由于B对象的锁被主线长占有,则副线程被阻塞,等待B对象的锁被主线程释放。最后,主线程和副线程相互等待对方释放锁发生死锁。




查看评论

Java学习指南系列(Java快速入门)

-
  • 1970年01月01日 08:00

java中死锁的概念是什么给个例子

当两个线程循环依赖于一对同步对象(monitor)时将发生死锁。马克-to-win例如:一个线程进入对象ObjA上的监视器,而另一个线程进入对象ObjB上的监视器。如果ObjA中的线程试图调用ObjB...
  • mark_to_win
  • mark_to_win
  • 2017-04-12 12:59:48
  • 724

java两种经典死锁例子,Lock发生死锁案列

第一种synchronized方式死锁,两个线程互相持有对方需要获取的锁。 第二种concurrent包Lock错误使用,导致死锁。 lock.unlock();释放锁使用地方不规范,导致死锁不能正常...
  • li396864285
  • li396864285
  • 2016-05-24 10:06:06
  • 12790

java死锁详解

进程死锁及解决办法:         一:死锁的概念:                 死锁是进程死锁的简称                 什么是死锁:                   ...
  • yubotianxiao
  • yubotianxiao
  • 2016-08-02 13:09:06
  • 1531

Java死锁的排查

先弄个死锁的代码例子: public class DeadLock implements Runnable { private int flagCurrent = -1; private s...
  • sidihuo
  • sidihuo
  • 2016-09-08 19:12:11
  • 1598

java中如何写一个死锁例子

你没看错,今天是要写一个死锁程序。通过自己写一个死锁例子,就能理解为什么会发生死锁。 但在写这个程序前,是不是要知道什么情况下才会发生死锁(假装我开头没说过那句话)。我们先抛开一系列复杂的业务逻辑,单...
  • qq_35064774
  • qq_35064774
  • 2016-06-30 21:42:17
  • 4342

Java多线程 线程同步与死锁

1.线程同步多线程引发的安全问题一个非常经典的案例,银行取钱的问题。假如你有一张银行卡,里面有5000块钱,然后你去银行取款2000块钱。正在你取钱的时候,取款机正要从你的5000余额中减去2000的...
  • kong_gu_you_lan
  • kong_gu_you_lan
  • 2017-02-25 15:47:18
  • 1570

一个简单的Java死锁示例

在实际编程中,要尽量避免出现死锁的情况,但是让你故意写一个死锁的程序时似乎也不太简单(有公司会出这样的面试题),以下是一个简单的死锁例子,程序说明都写着类的注释里了,有点罗嗦,但是应该也还是表述清楚了...
  • Hsuxu
  • Hsuxu
  • 2013-02-19 13:34:53
  • 22914

Java如何查看死锁?

ava中当我们的开发涉及到多线程的时候,这个时候就很容易遇到死锁问题,刚开始遇到死锁问题的时候,我们很容易觉得莫名其妙,而且定位问题也很困难。 因为涉及到java多线程的时候,有的问题会特别复杂,而且...
  • u014039577
  • u014039577
  • 2016-08-29 12:47:03
  • 3881

Java多线程产生死锁的条件以及解决方法

摘自《Thinking in Java》: 死锁产生的原因: 1.互斥条件。任务使用的资源至少一个是不能共享的。 2.至少有一个任务它必须持有一个资源且正在等待获取一个当前被别的任务持有的资源。...
  • kingzma
  • kingzma
  • 2015-03-26 02:01:41
  • 1273
    个人资料
    等级:
    访问量: 2076
    积分: 197
    排名: 119万+