我想知道是否存在这种说法是真实和需要的情况。我见过的所有例子都只在“this”引用上同步。有人能告诉我一个对象中的代码块如何在除此之外的任何其他引用上同步吗?
4 回答
是的,这句话是真的。
不希望使用内部监视器synchronized(this)
(多变的。如果另一个线程使用 A 的同一个实例并尝试运行a.methodA()
,它将被阻塞直到methodB()
结束。
因此,使用内部监视器会暴露同步策略,并可能导致细微的错误和性能问题。
public class A {
public synchronized void methodA() {}
}
public class B {
A a = new A();
public void methodB() {
synchronized(a) {
// do something a little long
}
}
public A getA() {return a;}
}
如果 A 使用了内部监视器,则不会出现该问题。
public class A {
private final Object lock = new Object();
public void methodA() {
synchronized(lock) {}
}
}
使用 ad hoc 监视器有意义的另一种情况是,当一个类包含 2 个(或更多)不相关的对象时,它们都需要以同步方式访问。使用 2 个监视器而不是一个监视器可以减少争用,因为现在可以同时访问 2 个对象。
在 Java 中,您可以使用synchronized
构造在任何对象引用上创建内在锁,是的。阅读相关的Java 教程。
不使用this的直接示例synchronized
是在Class
对象上同步时,这就是方法的static synchronized
工作方式。实际上,有很多有效的用途。您可能希望避免使用synchronized (this)
内部实现锁,否则您正在设置您在内部使用锁的限制,您不知道的其他代码可能会违反。
但是,您应该知道,通常您可以synchronized
用ReentrantLock
. 您可以在我的帖子中阅读更多相关信息。
是的,它可以做到。
同步块将使用该对象作为锁,而不是整个类。使用 synchronized(this) { } 的人对整个对象设置了排他锁,这可能是您想要的。但是,您可能有类似持久性的东西,这是唯一需要同步的东西。synchronized(persister) { },将提供一种不那么精细的方式来执行此操作。
public class SyncTest{
private Object obj = new Object();
public void func1() {
synchronized(obj) {
obj.something();
}
}