从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就可以上手了,

借一个图说明问题:

Ref: 1  2  3  4  5  6  7

时间: 2024-10-24 11:50:46

从FindBugs中学Java【五】的相关文章

从FindBugs中学Java【四】

5.TQ_ALWAYS_VALUE_USED_WHERE_NEVER_REQUIRED 6.TQ_COMPARING_VALUES_WITH_INCOMPATIBLE_TYPE_QUALIFIERS 7.TQ_EXPLICIT_UNKNOWN_SOURCE_VALUE_REACHES_ALWAYS_SINK 8.TQ_EXPLICIT_UNKNOWN_SOURCE_VALUE_REACHES_NEVER_SINK 9.TQ_MAYBE_SOURCE_VALUE_REACHES_ALWAYS_SI

从FindBugs中学Java【一】

findbug 这里[中文列表]: http://svn.codehaus.org/sonar-plugins/tags/sonar-l10n-zh-plugin-1.1/src/main/resources/org/sonar/l10n/findbugs_zh.properties rule.findbugs.IMSE_DONT_CATCH_IMSE.name=不良实践 - 捕获可疑IllegalMonitorStateException rule.findbugs.BX_BOXING_IMM

从FindBugs中学Java【二】

IMSE_DONT_CATCH_IMSE java.lang  Class IllegalMonitorStateException java.lang.Object   java.lang.Throwable       java.lang.Exception           java.lang.RuntimeException               java.lang.IllegalMonitorStateException All Implemented Interfaces:

从FindBugs中学Java【三】

2. BX_BOXING_IMMEDIATELY_UNBOXED double a = 100d; double d = Double.valueOf(a); Primitive value is boxed and then immediately unboxed. 非必要的装箱并立即拆箱操作. Intellij 也会给这样的提示: 没什么好说的 3. IJU_SETUP_NO_SUPER 好像是个遗留问题,出现在JUnit3的时代,e.g. JUnit3里会这么做 public class 

Java(五、类和对象中的例题)

一.方法中的参数为数值型的(int) import java.util.Scanner; public class ScoreCalc { public void calc(int num1,int num2,int num3){ int sum = num1 + num2 +num3; double avg = sum / 3; System.out.println("总成绩:"+sum); System.out.println("平均分:"+avg); } pu

Java(五)

♥作业1: 显示指定路径所有文件及实现文件筛选.智能监控,程序能自动在下拉菜单生成任意路径下文件所有尾缀.  代码内注释内容为步骤与整体思路  1 import java.awt.BorderLayout; 2 import java.awt.Color; 3 import java.awt.Font; 4 import java.awt.event.ActionEvent; 5 import java.awt.event.ActionListener; 6 import java.io.Fil

福州杨桥中学初二五班相关通知

一切以老师通知为准 时间 内容 2014-8-29 时间:8月31日上午8:30 地点:预计在杨桥中学3号楼二楼 需要带的材料: 1.英语作业 2.语文作业 3.数学作业:考卷 4.暑假之友 5.21天养成好习惯 ......等 2014-8-29 如何开展社区小分队.doc

[转]Java五个最常用的集合类之间的区别和联系

常用的集合类有一下几种: List结构的集合类:ArrayList类,LinkedList类,Vector类,Stack类 Map结构的集合类:HashMap类,Hashtable类 Set结构的集合类:HashSet类,TreeSet类 Queue结构的集合:Queue接口 HashMap和Hashtable的区别: HashMap和Hashtable都是java的集合类,都可以用来存放java对象,这是他们的相同点 以下是他们的区别: 1.历史原因: Hashtable是基于陈旧的Dicti

Java五种基本的Annotation,提高程序的可读性

从JDK5开始,Java增加了对元数据的支持,也就是Annotation(即注解也被翻译为注释). 这里的Annotation和普通的注释有一定的区别,它是代码中的特殊标记,这些标记可以在编译.类加载或者运行时被读取,并执行相应的处理.通过这样的注解,可以帮助开发人员在不改变原有的逻辑的情况下,在源文件中补充一些信息.而代码分析工具.开发工具和部署工具可以通过这些补充信息进行验证或者进行部署. Annotation可以用来为程序元素(类.方法.成员变量等)设置元数据,值得一提的是,它不会影响代码