Java同步方法问题

3

我有一个包含两个同步方法的类:

class Service {

 public synchronized void calc1();

 public synchronized void calc2();

}

这两种方法都需要相当长的时间来执行。问题是这两种方法的执行是否会互相阻塞。也就是说,这两种方法能否在不同的线程中并行执行?

3个回答

10

不可以在同一个服务上并行执行这两个方法 - 两种方法共享同一个监视器(即this),因此如果线程A正在执行calc1,那么线程B将无法获得监视器,因此无法运行calc2。(请注意,线程B可以在不同的实例中调用任一方法Service,因为它将尝试获取不同的未持有监视器,因为所涉及的this将是不同的。)

最简单的解决方案(假设您希望它们独立运行)是使用显式监视器执行以下操作:

class Service {
   private final Object calc1Lock = new Object();
   private final Object calc2Lock = new Object();

   public void calc1() {
       synchronized(calc1Lock) {
           // ... method body
       }
   }

   public void calc2() {
       synchronized(calc2Lock) {
           // ... method body
       }
   }

}

所谓的“锁”不需要具备除了作为对象并拥有特定监视器外的任何特殊能力。如果您有更复杂的要求,例如尝试锁定并立即回退或查询谁持有锁定,您可以使用实际的Lock对象,但对于基本情况,这些简单的Object锁就足够了。


2
嗯,但只有在同一对象上执行方法时才会生效。否则,它们可以同时执行,因为它们不是静态的。可能会有多个“Service”对象,问题没有对此进行说明。 - musiKk
@musiKk - 非常好的观点,并值得明确提出。我已经相应地更新了我的答案。 - Andrzej Doyle

1

是的,你可以在两个不同的线程中执行它们,而不会破坏你的类内部,但不会并行运行 - 每次只有一个会被执行。


0
不可以。在这种情况下,您可以使用 synchronized 块来代替同步整个方法。不要忘记在不同的对象上进行同步。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接