繁体   English   中英

在Java中,同步块可以在任何对象引用上进行同步吗?

[英]In Java, synchronized block can synchronize on any object reference?

我想知道是否有这种说法是正确和必要的。 我看到的所有示例仅在“ this”参考上同步。 有人可以告诉我一个对象中的代码块如何在除此以外的任何其他引用上同步吗?

是的,陈述是正确的。

有几个原因使您不希望使用内部监视器( synchronized(this) )-其中一个原因是它可能会引起活动性问题-在下面的代码中,B使用A的实例作为锁,也许控制对该变量的访问。 如果另一个线程使用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) {}
    }

}

使用临时监视器有意义的另一种情况是,当一个类包含2个(或更多)不相关的对象时,两个对象都需要以同步方式进行访问。 使用2个监视器而不是1个监视器可以减少争用,因为现在可以同时访问2个对象。

在Java中,可以使用synchronized构造在任何对象引用上创建内在锁,是的。 阅读相关的Java教程

使用synchronized的直接示例是在Class对象上synchronized时,这就是static synchronized方法的工作方式 实际上,有很多有效的用途。 您可能希望避免使用synchronized (this)来支持内部实现锁,否则您将设置内部使用该锁的限制,而您不知道的其他代码可能会违反该限制。

但是,您应该知道,通常您可以用ReentrantLock替换synchronized用法。 您可以在我的文章中阅读更多有关此内容的信息

是的,它可以做到。

同步块将使用该对象作为锁,而不是整个类。 使用synced(this){}的人对整个对象设置了排他锁,这可能就是您想要的。 但是,您可能会有类似持久性的东西,这是唯一需要同步的东西。 synced(persister){},将提供一种粒度较小的方法。

public class SyncTest{
    private Object obj = new Object();

    public void func1() {
        synchronized(obj) {
            obj.something();
        }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM