如何避免死锁

2018-12-11  本文已影响0人  响响月月

死琐

A线程持有a锁,等待获取b锁;同时B线程持有b锁,等待获取a锁。

死琐条件

-- 独占锁:

-- 循环等待:若干个进程形成环形链,每个都占用对方申请的下一个资源。

    public static void main(String[] args) {
        final Object a = new Object();
        final Object b = new Object();
        Thread threadA = new Thread(() -> {
            synchronized (a) { //sleep 下可以确保死锁
                System.out.println("now i in threadA-locka");
                synchronized (b) {
                    System.out.println("now i in threadA-lockb");
                }
            }
        });
        Thread threadB = new Thread(() -> {
            synchronized (b) { //sleep 下可以确保死锁
                System.out.println("now i in threadB-lockb");
                synchronized (a) {
                    System.out.println("now i in threadB-locka");
                }
            }
        });
        threadA.start();
        threadB.start();
    }

如何避免

  1. 设置优先级
  2. 超时放弃

ReentrantLock接口中: boolean tryLock(long time, TimeUnit unit)
设置超时时间,超时可以退出防止死锁。

  1. 特定顺序 A->B->C
  2. 尽量降低锁的使用粒度,尽量不要几个功能用同一把锁,能锁块不锁方法
  3. 不要用锁
银行家算法
  1. 固定数量的进程,固定数量的资源
  2. 进程预先指定工作所需最大资源
  3. 进程不能申请比总资源还多的资源
  4. 进程等待时间有限
  5. 进程在有限时间使用资源,用完归还
  1. Request[i] <= need[i]
  2. Request[i] <= Available
  3. 分配资源,调整状态
    Available = Available - Request[i]
    Allocation[i] = Allocation[i] + Request[i]
    Need[i] = Need[i] - Request[i]
  4. 判断新状态是否有效,无效则退回,进程等待
    初始化:Work = Available, finished = false
    检测:Need[i] <= Work

检测死锁

  1. jstack
    Jstack工具可以用于生成java虚拟机当前时刻的线程快照。线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等。

jps 查端口号
jstack pid

  1. jconsole
    图形化工具
上一篇 下一篇

猜你喜欢

热点阅读