参考如下代码,在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对这种情况会报错,锁对象选择不当。
本文通过一个具体的Java示例,展示了如何使用synchronized关键字实现线程间的锁机制,并深入探讨了当使用相同的字符串常量作为锁对象时出现的竞争问题。通过对比不同锁对象的选择,揭示了字符串常量作为锁带来的潜在问题。
1778

被折叠的 条评论
为什么被折叠?



