简体   繁体   English

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

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

I was wondering if there is a situation where this statement will be true and needed. 我想知道是否有这种说法是正确和必要的。 All the examples I have seen only synchronize on the "this" reference. 我看到的所有示例仅在“ this”参考上同步。 Can someone tell me how a block of code in one object can be synchronized on any other reference apart from this ? 有人可以告诉我一个对象中的代码块如何在除此以外的任何其他引用上同步吗?

Yes the statement is true. 是的,陈述是正确的。

There are several reasons why one would want NOT to use an intrinsic monitor ( synchronized(this) ) - one of these reasons is that it can create liveness issues - in the code below, B uses an instance of A as a lock, maybe to control access to that variable. 有几个原因使您不希望使用内部监视器( synchronized(this) )-其中一个原因是它可能会引起活动性问题-在下面的代码中,B使用A的实例作为锁,也许控制对该变量的访问。 If another thread uses that same instance of A and tries to run a.methodA() , it will be blocked until methodB() is over. 如果另一个线程使用A的相同实例并尝试运行a.methodA() ,它将被阻塞,直到methodB()

So using an intrinsic monitor exposes the synchronization policy and can lead to subtle bugs and performance issues. 因此,使用内部监视器会暴露同步策略,并可能导致细微的错误和性能问题。

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;}
}

If A had used an internal monitor that problem would not be possible. 如果A使用了内部监视器,则不可能出现此问题。

public class A {
    private final Object lock = new Object();

    public void methodA() {
        synchronized(lock) {}
    }

}

Another scenario where using ad hoc monitors makes sense is when a class contains 2 (or more) unrelated objects, that both need to be accessed in a synchronized manner. 使用临时监视器有意义的另一种情况是,当一个类包含2个(或更多)不相关的对象时,两个对象都需要以同步方式进行访问。 Using 2 monitors instead of one reduces contention as the 2 objects can now be accessed concurrently. 使用2个监视器而不是1个监视器可以减少争用,因为现在可以同时访问2个对象。

In Java, you can use synchronized constructs to create instrinsic locks on any object reference, yes. 在Java中,可以使用synchronized构造在任何对象引用上创建内在锁,是的。 Read the relevant Java Tutorial . 阅读相关的Java教程

The immediate example of not using synchronized with this is when synchronizing on the Class object, which is how static synchronized methods work . 使用synchronized的直接示例是在Class对象上synchronized时,这就是static synchronized方法的工作方式 In reality, there are plenty of valid uses. 实际上,有很多有效的用途。 You may want to avoid using synchronized (this) in favor of an internal implementation lock as otherwise you are setting a restriction that you use the lock internally, which other code you're not aware of might violate. 您可能希望避免使用synchronized (this)来支持内部实现锁,否则您将设置内部使用该锁的限制,而您不知道的其他代码可能会违反该限制。

You should know, however, that often times you can replace synchronized usage with a ReentrantLock . 但是,您应该知道,通常您可以用ReentrantLock替换synchronized用法。 You can read more about this in my post here . 您可以在我的文章中阅读更多有关此内容的信息

Yes it can be done. 是的,它可以做到。

The synchronize block will use that object as a lock, rather than the whole class. 同步块将使用该对象作为锁,而不是整个类。 People that use synchronized(this) { } put an exclusive lock on the whole object, which might be what you want. 使用synced(this){}的人对整个对象设置了排他锁,这可能就是您想要的。 However, you might have something like a persister, which is the only thing that needs to be synchronized. 但是,您可能会有类似持久性的东西,这是唯一需要同步的东西。 synchronized(persister) { }, would provide a less granular way of doing 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