参考如下代码,在BadLockA和BadLockB中我们使用了BADLOCK字符串作为锁对象(这个字符串对象我们加不加static final修饰都一样)
public class Test
{
public static void main(String[] args) throws Exception
{
BadLockA lockA = new BadLockA();
BadLockB lockB = new BadLockB();
new Thread(lockA).start();
new Thread(lockB).start();
}
}
class BadLockA implements Runnable
{
private String LOCK = "BADLOCK";
@Override
public void run()
{
synchronized (LOCK)
{
try
{
while (true)
{
System.out.println("BadLockA access method success!");
Thread.sleep(1000);
System.out.println("BadLockA release the lock");
}
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
class BadLockB implements Runnable
{
private String LOCK = "BADLOCK";;
@Override
public void run()
{
synchronized (LOCK)
{
try
{
while (true)
{
System.out.println("BadLockB access method success!");
Thread.sleep(1000);
System.out.println("BadLockB release the lock");
}
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
执行可以看到只有1个线程一直获取锁了,另一个始终获取不到,说明2个线程使用的锁对象都是同一个。
修改锁对象为
private Object obj = new Object();
再次运行,则可以发现2个线程都可以交替获取到锁了。这个报错的原因就是,字符串常量是保存在JVM方法区里,所以2个线程锁定的是同一块内存区,也就导致看起来是2个线程里各自定义的变量,但是是同一个,所以coverity对这种情况会报错,锁对象选择不当。