Java 死锁相关的一道经典面试题

Posted 码农每日一题

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 死锁相关的一道经典面试题相关的知识,希望对你有一定的参考价值。

码农每日一题
长按关注,工作日每天分享一个技术知识点。
Java 死锁相关的一道经典面试题

问:什么是死锁?请模拟写出一段 Java 死锁的核心代码?如何避免死锁?


答:关于什么是死锁其实就是陷入互相等待谁都无法执行的一种状态,譬如有 A B 两个线程,A 持有 LockA 锁且在等待 LockB 锁,而 B 持有锁 LockB 且在等待 LockA 锁,LockA LockB 陷入互相等待导致谁都无法执行的一种现象。当发生死锁可以采用 jstack 命令进行分析,android 上面可以采用 Android Device Monitor Thread 进行分析。

关于死锁的核心代码例子如下:

  
    
    
  
  1. public class ThreadLoop {

  2.    private static Object mLockA = new Object();

  3.    private static Object mLockB = new Object();


  4.    private static void startThreadA() {

  5.        new Thread() {

  6.            @Override

  7.            public void run() {

  8.                Log.i("YYYY", "startThreadA running!");

  9.                synchronized (mLockA) {

  10.                    Log.i("YYYY", "startThreadA mLockA enter!");

  11.                    ThreadLoop.sleep(200);

  12.                    synchronized (mLockB) {

  13.                        Log.i("YYYY", "startThreadA mLockB enter!");

  14.                    }

  15.                }

  16.                Log.i("YYYY", "startThreadA over!");

  17.            }

  18.        }.start();

  19.    }


  20.    private static void startThreadB() {

  21.        new Thread() {

  22.            @Override

  23.            public void run() {

  24.                Log.i("YYYY", "startThreadB running!");

  25.                synchronized (mLockB) {

  26.                    Log.i("YYYY", "startThreadB mLockB enter!");

  27.                    ThreadLoop.sleep(200);

  28.                    synchronized (mLockA) {

  29.                        Log.i("YYYY", "startThreadB mLockA enter!");

  30.                    }

  31.                }

  32.                Log.i("YYYY", "startThreadB over!");

  33.            }

  34.        }.start();

  35.    }


  36.    private static void sleep(long time) {

  37.        try {

  38.            Thread.sleep(time);

  39.        } catch (InterruptedException e) {

  40.            e.printStackTrace();

  41.        }

  42.    }


  43.    public static void start() {

  44.        startThreadA();

  45.        startThreadB();

  46.    }

  47. }

运行结果可能如下:

  
    
    
  
  1. startThreadA running!

  2. startThreadA mLockA enter!

  3. startThreadB running!

  4. startThreadB mLockB enter!

  5. //陷入死锁...

避免死锁其实主要有如下几个经验:

考虑加锁顺序:当多个线程需要相同的一些锁但每个线程又按照不同顺序加锁则很容易发生死锁(如上面死锁的例子),如果能确保所有的线程都是按照相同的顺序获得锁则发生死锁的情况就不存在了。

考虑加锁时限:可以在尝试获取锁的时候加一个超时时间,若一个线程没有在给定的时限内成功获得所有需要的锁则会进行回退并释放所有已经获得的锁,然后等待一段随机的时间再重试,这段随机的等待时间让其它线程有机会尝试获取相同的这些锁,并且让该应用在没有获得锁的时候可以继续运行。

Java 死锁相关的一道经典面试题

《》

《》

看完不过瘾?看完还想看?那就点击左下角阅读原文查看本号历史经典技术知识点题目推送,解锁更多基础知识~

以上是关于Java 死锁相关的一道经典面试题的主要内容,如果未能解决你的问题,请参考以下文章

Java类与对象初始化的过程(一道经典的面试题)

一道经典的Java面试题:equals ,== 和hashcode()的区别

面试题系列论JDK源码一道经典面试题

JAVA面试集锦String相关的经典面试题

一道经典面试题讲解 :数组越界而没报错 ,却出现死循环 ?(C语言)

99%的面试官都会问到的Java面试题