Java 中的同步是如何工作的?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11184642/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 04:06:58  来源:igfitidea点击:

How Synchronization works in Java?

javathread-synchronization

提问by Raj

I have a doubt regarding Java Synchronization . I want to know if I have three Synchronized methods in my class and a thread acquires lock in one synchronized method other two will be locked ? I am asking this question because I am confused with the following statement .

我对 Java Synchronization 有疑问。我想知道我的类中是否有三个 Synchronized 方法并且一个线程在一个同步方法中获取锁,另外两个将被锁定?我问这个问题是因为我对以下陈述感到困惑。

While a thread is inside a synchronized method of an object, all other threads that wish to execute this synchronized method or any other synchronized method of the object will have to wait. This restriction does not apply to the thread that already has the lock and is executing a synchronized method of the object. Such a method can invoke other synchronized methods of the object without being blocked. The non-synchronized methods of the object can of course be called at any time by any thread

当线程在对象的同步方法内时,所有其他希望执行此同步方法或对象的任何其他同步方法的线程都必须等待。这个限制不适用于已经拥有锁并且正在执行对象的同步方法的线程。这样的方法可以调用对象的其他同步方法而不会被阻塞。对象的非同步方法当然可以被任何线程随时调用

采纳答案by bezmax

Synchronization in java is done through aquiering the monitor on some specific Object. Therefore, if you do this:

java中的同步是通过在某个特定对象上获取监视器来完成的。因此,如果您这样做:

class TestClass {
    SomeClass someVariable;

    public void myMethod () {
        synchronized (someVariable) {
            ...
        }
    }

    public void myOtherMethod() {
        synchronized (someVariable) {
            ...
        }
    }
}

Then those two blocks will be protected by execution of 2 different threads at any time while someVariableis not modified. Basically, it's said that those two blocks are synchronized against the variable someVariable.

然后这两个块将在someVariable不被修改的情况下随时执行 2 个不同的线程来保护。基本上,据说这两个块与变量同步someVariable

When you put synchronizedon the method, it basically means the same as synchronized (this), that is, a synchronization on the object this method is executed on.

当你套上synchronized这个方法时,它的意思基本上和 一样synchronized (this),也就是对执行这个方法的对象进行同步。

That is:

那是:

public synchronized void myMethod() {
    ...
}

Means the same as:

意思相同:

public void myMethod() {
    synchronized (this) {
       ...
    }
}

Therefore, to answer your question - yes, threads won't be able to simultaneously call those methods in different threads, as they are both holding a reference to the same monitor, the monitor of thisobject.

因此,要回答您的问题 - 是的,线程将无法在不同线程中同时调用这些方法,因为它们都持有对同一监视器(this对象监视器)的引用。

回答by xyz

Yes.
To execute synchronized method thread need to obtain lock on object and only one thread at a time can obtain lock on object.

是的。
执行同步方法线程需要获取对象锁,并且一次只有一个线程可以获取对象锁。

回答by Miquel

Each java object (class instance) has a mutex object. The synchronized keyword in front of a method means that the running thread has to get the lock on the mutex for that object. In fact,

每个 java 对象(类实例)都有一个互斥对象。方法前面的 synchronized 关键字意味着正在运行的线程必须为该对象获取互斥锁。实际上,

public synchronized doSomething(){
   ...
}

Is exactly the same as this:

和这个完全一样:

public  doSomething(){
   synchronized(this){
      ...
   }
}

So yes, there will only be one thread executing a synchronized method per class instance.

所以是的,每个类实例只会有一个线程执行同步方法。

Note that sometimes this can be suboptimal, since you want to protect modifications, but are fine with concurrent reads, in which case, instead of the synchronized keyword, you might want to look into ReadWriteLock.

请注意,有时这可能不是最理想的,因为您想要保护修改,但对于并发读取没问题,在这种情况下,您可能需要查看ReadWriteLock而不是 synchronized 关键字。

回答by Johannes Weiss

Yes, all threads but the one which acquired the lock will have to wait until the lock gets released again to be able to execute one of the three synchronized methods.

是的,除了获得锁的线程之外的所有线程都必须等到锁再次被释放才能执行三种同步方法之一。

Remember, a synchronized method is the same as a normal method surrounded by

请记住,同步方法与被包围的普通方法相同

synchronized(this) {
    // method body
} 

回答by Pramod Kumar

It is true and it does in this way. It is necessary as well to consistent the data of that object.

确实如此,而且确实如此。还必须使该对象的数据保持一致。

Suppose that this validation is not there and there is a variable x which is being manipulated by 2 different synchronized method xxx() and yyy().

假设此验证不存在,并且有一个变量 x 由 2 个不同的同步方法 xxx() 和 yyy() 操作。

so if Thread A gets lock of method xxx() which is manipulating x=5 and second thread B gets lock of method yyy() and manipulating x=-5 so in the end of method xxx() thread A is expecting x=5 but it will get x=0 that is wrong.

因此,如果线程 A 获得方法 xxx() 的锁定,该方法正在操纵 x=5,而第二个线程 B 获得方法 yyy() 的锁定并操纵 x=-5,那么在方法 xxx() 的末尾,线程 A 期望 x=5但它会得到 x=0 这是错误的。

Thats why it is implemented in this way.

这就是它以这种方式实施的原因。

回答by Farhaz Malik

If a class has 4 synchronize methods, then yes at a time only one thread will have access to those methods. I guess doubt here was, each thread can access diff synchronized methods at a time for single class instance. The answer is no. Only one thread can access synchronized methods at a time.

如果一个类有 4 个同步方法,那么一次只有一个线程可以访问这些方法。我想这里的疑问是,每个线程都可以一次访问单个类实例的 diff 同步方法。答案是不。一次只有一个线程可以访问同步方法。

回答by Ahmad

well, there is only one lock per object. and all synchronized methods are locked by this lock. So , whichever thread acquires lock at a time, it is authorized to go through all synchronized methods. But the threads which waits for the lock can't enter into synchronize methods until they get the lock.

好吧,每个对象只有一个锁。并且所有同步方法都被这个锁锁定。因此,无论哪个线程一次获取锁,它都被授权通过所有同步方法。但是等待锁的线程在获得锁之前不能进入同步方法。

So at a time only only thread rules and others have to wait to enter any synchronized method, doesn't matter the ruling thread is executing that method or not.

所以一次只有线程规则和其他人必须等待进入任何同步方法,不管统治线程是否正在执行该方法。

回答by user207421

I'm not sure what it is you find confusing, but acquiring a lock blocks other threads from acquiring it while you hold it, and all non-static synchronized methods of a class synchronize on the same object, so the answer to your question is 'yes', assuming I have understood you correctly. I don't know what else 'synchronized' could mean, or what use it would be with any other meaning.

我不确定是什么让您感到困惑,但是获取锁会阻止其他线程在您持有它时获取它,并且类的所有非静态同步方法都在同一个对象上同步,因此您的问题的答案是'是',假设我已经正确理解你。我不知道“同步”还有什么含义,或者它与任何其他含义有什么用处。