我有一个包含两个同步方法的类:
class Service {
public synchronized void calc1();
public synchronized void calc2();
}
这两种方法都需要相当长的时间来执行。问题是这两种方法的执行是否会互相阻塞。也就是说,这两种方法能否在不同的线程中并行执行?
我有一个包含两个同步方法的类:
class Service {
public synchronized void calc1();
public synchronized void calc2();
}
这两种方法都需要相当长的时间来执行。问题是这两种方法的执行是否会互相阻塞。也就是说,这两种方法能否在不同的线程中并行执行?
不可以在同一个服务上并行执行这两个方法 - 两种方法共享同一个监视器(即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
锁就足够了。
是的,你可以在两个不同的线程中执行它们,而不会破坏你的类内部,但不会并行运行 - 每次只有一个会被执行。
synchronized
块来代替同步整个方法。不要忘记在不同的对象上进行同步。