Java并发——死锁

死锁:多个线程并发执行,存在多个线程循环等待资源的情形,没有外力干扰,线程都处于等待的状态。
死锁产生的原因:1.对不可剥夺资源的竞争2.进程推进顺序非法
死锁产生的必要条件:
- 互斥条件:资源在一段时间内只能被一个线程占有
- 不可剥夺条件:线程持有资源后不能被其他线程抢占
- 请求和保持条件:线程持有一个资源后,在不释放资源的情形下继续请求资源。
- 循环等待条件:线程之间出现循环等待资源的情形。
对待死锁:

  • 死锁预防:破坏死锁必要条件
  • 死锁避免:银行家算法
  • 死锁检测:
public class DeadLock {

    private String id;

    public DeadLock(String id) {
        this.id = id;
    }

    public synchronized void checkOther(DeadLock other) {
        System.out.println(Thread.currentThread().getName()+"entering checkOther");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {

        }
        System.out.println(Thread.currentThread().getName()+"tyring action");
        other.action();
        System.out.println(Thread.currentThread().getName()+"exit checkOther");
    }
    public synchronized void action() {
        System.out.println(Thread.currentThread().getName()+"entering action");
        try {
            Thread.sleep(2000);
        } catch (Exception e) {

        }
        System.out.println(Thread.currentThread().getName()+"exit action");
    }
    public static void main(String[] args) {
        DeadLock lock1 = new DeadLock("obj1");
        DeadLock lock2 = new DeadLock("obj2");
        new Thread(new Runnable() {

            @Override
            public void run() {

                lock1.checkOther(lock2);

            }
        }).start();
        new Thread(new Runnable() {

            @Override
            public void run() {

                lock2.checkOther(lock1);

            }
        }).start();
    }

}

这是结果:

Thread-0entering checkOther
Thread-1entering checkOther
Thread-0tyring action
Thread-1tyring action

线程0 在获取lock1对象的锁之后试图获取lock2的锁,而线程1 在获取lock2对象的锁之后试图获取lock1的锁,出现循环等待的情形,就出现死锁现象。
这里出现死锁是因为两个线程差不多分别获得了lock1和lock2的锁,若线程2获取lock1锁的时间迟一点,就不会出现死锁的情形,说明我们可以通过减少加锁时间,错开不同线程获得锁的时间来避免死锁。

Java中怎么处理死锁:

  1. 线程按照一定顺序枷锁
  2. 加锁时限(线程尝试获取锁的时候设置一定时限,超过时限还没有获得锁就释放已有的锁)
  3. 检测是否出现死锁,然后处理死锁

    怎么检测?
    每当一个线程获得了锁,会在线程和锁相关的数据结构中(map、graph等等)将其记下。除此之外,每当有线程请求锁,也需要记录在这个数据结构中。
    当一个线程请求锁失败时,这个线程可以遍历锁的关系图看看是否有死锁发生。例如,线程A请求锁7,但是锁7这个时候被线程B持有,这时线程A就可以检查一下线程B是否已经请求了线程A当前所持有的锁。如果线程B确实有这样的请求,那么就是发生了死锁(线程A拥有锁1,请求锁7;线程B拥有锁7,请求锁1)。
    死锁发生后解决办法:1.释放锁,回退,然后等待一段时间重试。2.给线程设置优先级,让一个或者几个线程回退。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值