从FindBugs中学Java【五】

13. TLW_TWO_LOCK_WAIT

 

TLW: Wait with two locks held (TLW_TWO_LOCK_WAIT)

Waiting on a monitor while two locks are held may cause deadlock.   Performing a wait only releases the lock on the object being waited on, not any other locks.   This not necessarily a bug, but is worth examining closely.

关于这个问题,我们回归下基础,

Tanenbaum的《现代操作系统》里这么解释的死锁:

  A deadlock occurs when a set of processes are blocked waiting for an event that only some other process in the set can cause. On the other hand, processes in a livelock are not blocked. Instead, they continue to execute checking for a condition to become true that will never become true. Thus, in addition to the resources they are holding, processes in livelock continue to consume precious CPU time. Finally, starvation of a process occurs because of the presence of other processes as well as a stream of new incoming processes that end up with higher priority that the process being starved. Unlike deadlock or livelock, starvation can terminate on its own, e.g. when existing processes with higher priority terminate and no new processes with higher priority arrive.

汤子赢的《计算机操作系统》里会这么教我们:

四个必要条件:互斥条件,请求和保持条件,不剥夺条件和环路等待条件.

处置方案:预防死锁,避免死锁,检测死锁和解除死锁;

举个死锁的例子:

public class TestLock implements Runnable {
 public int flag;
 public static Object o1 = new Object();
 public static Object o2 = new Object();
 public static void main(String[] args) {
  TestLock tl1 = new TestLock();
  TestLock tl2 = new TestLock();
  tl1.flag = 1;
  tl2.flag = 0;
  Thread t1 = new Thread(tl1);
  Thread t2 = new Thread(tl2);
  t1.start();
  t2.start();
 }
 @Override
 public void run() {
  if (flag == 0) {
   synchronized (o1) {
    System.out.println("o1 lock");
    try {
     Thread.sleep(100);
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
    synchronized (o2) {
     System.out.println("o2 lock");
    }
   }
  }
  if (flag == 1) {
   synchronized (o2) {
    System.out.println("lock o2");
    try {
     Thread.sleep(100);
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
    synchronized (o1) {
     System.out.println("lock o1");
    }
   }
  }
 }
}

生产环境比较常见的问题吧,当然报错这种问题应该code review时就排除掉了,主要说那些隐藏的死锁,Performance Team会遇到这种情况多一些。

一般入门分析的话,看看jstack就可以上手了,

借一个图说明问题:

从FindBugs中学Java【五】_第1张图片

Ref: 1  2  3  4  5  6  7

你可能感兴趣的:(从FindBugs中学Java【五】)