Как синхронизация работает в Java?

У меня есть сомнения относительно синхронизации Java. Я хочу знать, есть ли у меня три метода Synchronized в моем классе, и поток получает блокировку в одном синхронизированном методе, другие два будут заблокированы? Я задаю этот вопрос, потому что меня путают со следующим утверждением.

Пока поток находится внутри синхронизированного метода объекта, все остальные потоки, которые хотят выполнить этот синхронизированный метод или любой другой синхронизированный метод объекта, должны будут ждать. Это ограничение не распространяется на поток, который уже имеет блокировку и выполняет синхронизированный метод объекта. Такой метод может вызывать другие синхронизированные методы объекта без блокировки. Несинхронизированные методы объекта можно, конечно, вызывать в любой момент любым потоком

Ответ 1

Синхронизация в java осуществляется путем добавления монитора к определенному объекту. Поэтому, если вы это сделаете:

class TestClass {
    SomeClass someVariable;

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

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

Затем эти два блока будут защищены при выполнении двух разных потоков в любое время, пока someVariable не будет изменен. В основном, он сказал, что эти два блока синхронизированы с переменной someVariable.

Когда вы помещаете synchronized в метод, он в основном означает то же, что и synchronized (this), то есть синхронизация на объекте, в котором этот метод выполняется.

То есть:

public synchronized void myMethod() {
    ...
}

Означает то же, что:

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

Поэтому, чтобы ответить на ваш вопрос - да, потоки не смогут одновременно вызвать эти методы в разных потоках, так как они оба держат ссылку на тот же монитор, монитор объекта this.

Ответ 2

Да.
Для выполнения синхронизированного потока метода необходимо получить блокировку объекта, и только один поток за один раз может получить блокировку объекта.

Ответ 3

Каждый объект java (экземпляр класса) имеет объект mutex. Синхронизированное ключевое слово перед методом означает, что текущий поток должен получить блокировку для мьютекса для этого объекта. Фактически,

public synchronized doSomething(){
   ...
}

Точно так же, как это:

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

Итак, да, будет только один поток, выполняющий синхронизированный метод для каждого экземпляра класса.

Обратите внимание, что иногда это может быть субоптимальным, так как вы хотите защитить модификации, но в порядке с одновременными чтениями, и в этом случае вместо ключевого слова synchronized вы можете посмотреть ReadWriteLock.

Ответ 4

ну, на объект есть только один замок. и все синхронизированные методы блокируются этой блокировкой. Итак, какая бы ни была ни одна цепочка за один раз блокируется за один раз, она имеет право пройти все синхронизированные методы. Но потоки, которые ждут блокировки, не могут вводить методы синхронизации, пока не получат блокировку.

Поэтому в то время только правила потоков и другие пользователи должны ждать, чтобы ввести какой-либо синхронизированный метод, не имеет значения, что управляющий поток выполняет этот метод или нет.

Ответ 5

Да, все потоки, кроме тех, которые приобрели блокировку, должны будут ждать, пока блокировка снова будет выпущена, чтобы иметь возможность выполнить один из трех синхронизированных методов.

Помните, что синхронизированный метод совпадает с обычным методом, окруженным

synchronized(this) {
    // method body
} 

Ответ 6

Это правда, и так происходит. Необходимо также согласовать данные этого объекта.

Предположим, что этой проверки нет, и существует переменная x, которой манипулируют 2 разных синхронизированных метода xxx() и yyy().

поэтому, если Thread A получает блокировку метода xxx(), который манипулирует x = 5, а второй поток B получает блокировку метода yyy() и манипулирует x = -5, поэтому в конце метода xxx() ожидается ожидание потока A x = 5, но он получит x = 0, что неверно.

Вот почему это реализовано таким образом.

Ответ 7

Если у класса есть 4 метода синхронизации, тогда да только один поток будет иметь доступ к этим методам. Я думаю, сомневаюсь, что каждый поток может получить доступ к синхронным методам синхронизации одновременно для экземпляра одного класса. Ответ - нет. Только один поток может одновременно получать синхронизированные методы.

Ответ 8

Я не уверен, что вы находите запутанным, но получение блокировки блокирует другие потоки от его приобретения, пока вы его удерживаете, и все нестатические синхронизированные методы класса синхронизируются на одном и том же объекте, поэтому ответ на ваш вопрос "да", если я правильно вас понял. Я не знаю, что еще может означать "синхронизированное", или какое использование было бы с любым другим значением.