我正在测试一个代码,其中有2个方法,并且每个方法中的一条语句都是同步的。

private final Object obj1 = new Object();
private final Object obj2 = new Object();

public void method1(int result)
{
 //there's a loop to create delay

 synchronized (obj1){
   sum = sum + result;
 }

 //there's a loop to create delay

}


public void method2(int result)
{
  //there's a loop to create delay

 synchronized (obj2){
   sum = sum - result;
 }

 //there's a loop to create delay

}


我基本上在做什么,就是将一个结果加到总和上,然后减去相同的数量,然后打印总和。因此,我的初始和最终金额应保持不变。

问题是当我使用2个diff对象作为锁时,我不知道为什么最终金额与初始金额不相同。但是,当我使用“ this”对象作为两个语句的锁时,它是恒定的。但是,使用“ this”作为对象并没有使执行时间比使用同步方法快。

我还是同步概念的新手,因此不胜感激。

最佳答案

当您在synchronize块中指定一个对象时,该对象就像该块的锁一样使用:只有一个synchronize块可以随时使用锁对象。

当您将两个不同的对象用作锁时,它们将变为两个不同的锁:两个线程可以同时锁定它们-每个锁一个线程。这解释了不一致的结果:两个线程可以同时获取两个单独的锁,并同时修改sum,从而导致计算错误。

您应该使用单个锁来保护单个资源免受并发访问。这是使用this时发生的情况;如果在两个obj1块中都使用obj2synchronize,也会发生同样的情况,除非在这种情况下,对象的用户将无法通过在对象上进行同步来使方法永远阻塞,而故意释放锁。

关于java - 与2个对象同步的块不起作用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12646815/

10-17 02:43