【问题标题】:Obtaining the lock ofan object by running its synchronized method通过运行对象的同步方法获取对象的锁
【发布时间】:2014-06-18 08:46:30
【问题描述】:

运行同步方法会将其对象的锁提供给调用该方法的人。

thisQ的代码中, 我需要在对象c 本身或其他任何东西上同步块吗?

setInt() 是一种同步方法。

在一行

c.setInt(c.getInt()+k); 

setInt()被调用时,由于setInt()是同步的,所以获得c的锁并且 在setInt() 返回之前不会释放锁。这就是整个区块,不需要同步它(?)

所以,

 c.setInt(c.getInt()+k); 

如果我在以下代码中注释掉“Line-A”和“Line-B”,仍然会同步。 setInt() 在这里同步,getInt() 不同步:

public void update(SomeClass c) {

    while (<condition-1>) // the conditions here and the calculation of 
                               // k below dont have anything to do 
                               // with the members of c
        if (<condition-2>) {
            // calculate k here 
            synchronized (c) {      // Line-A                  
                    c.setInt(c.getInt()+k); 
                //    System.out.println("in "+this.toString());
            }                      // Line-B
        }  
}

这让我一直很好奇。

TIA

【问题讨论】:

  • 不要向 SO 提出关于同一问题的大量问题。顺便说一句,我给了你一个answer to your first question,这样就不需要其他所有的东西了。

标签: java multithreading synchronization locking


【解决方案1】:

你的问题很难理解,但我认为你是在问你是否被锁定在那里的完整呼叫序列,答案是你没有。实际上,您输入的内容与以下内容相同:

 int tmp = c.getInt(); // will lock and then unlock c
 tmp += k;
 c.setInt(tmp); // will lock and then unlock c.

这就是为什么为了适当的线程安全,您需要一种在一个同步块中同时执行 get 和 set 的增量方法。

 c.increment(k);

【讨论】:

  • 或者只使用 AtomicInteger :P
  • @omu_negru 是的,这对于这种特定情况会更好。在一般情况下,您需要了解此行为才能正确执行线程。
  • 我在 setInt() 中调用 getInt()。 getInt 未同步,getInt() 是
  • @roam 您没有从 setInt 中调用 getInt。您正在将调用 getInt 的结果作为参数传递给 setInt。您在代码中的行与我使用 tmp 发布的行在功能上相同,并且应该清楚地说明为什么您确实需要同步块。
猜你喜欢
  • 2023-04-04
  • 1970-01-01
  • 1970-01-01
  • 2011-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-25
相关资源
最近更新 更多