1

我正在测试一个代码,其中我有 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 个差异对象作为锁时,我不知道为什么最终数量与初始数量不同。但是,当我使用“this”对象作为两个语句的锁时,它是不变的。但是使用“this”作为对象并没有比使用同步方法更快地执行时间。

我对同步概念仍然很陌生,因此不胜感激。

4

2 回答 2

2

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

当你使用两个不同的对象作为锁时,它们就变成了两个不同的锁:两个线程可以同时锁住它们——每个锁一个线程。这解释了结果不一致的原因:两个线程可以同时抓取两个单独的锁,并同时修改sum,导致计算不正确。

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

于 2012-09-28T20:20:03.090 回答
0

如果您synchronized想在obj1.obj2sum

否则,每个线程都会获得一个对象的锁定,并且它们可以同时执行操作。

每个线程在执行任何受保护的代码之前都会获取对象锁定。T1可能会同时获取锁,Obj1可能T2Obj2同时获取锁并继续执行,这可能会产生不一致的结果。

于 2012-09-28T20:17:50.040 回答