Подтвердить что ты не робот

Вопрос о синхронизации Java

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

например. класс Worker имеет метод под названием process(). У нас есть несколько экземпляров Worker, работающих в их собственных потоках. Мы хотим предотвратить одновременное использование нескольких методов экземпляра(). Будет ли синхронизировано это делать?

Спасибо.

4b9b3361

Ответ 1

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

Если вам нужно убедиться, что только один поток может выполнить метод во всех экземплярах, вы должны сделать метод static или сделать метод не synchronized и скорее использовать блок synchronized внутри метода, чтобы блокировка в поле private static.

Изменить: Обратите внимание, что синхронизация в переменной экземпляра private предпочтительнее иметь метод synchronized или синхронизировать с this, а блокировка в переменной экземпляра private static предпочтительнее иметь static synchronized метод или метод экземпляра, который синхронизируется на this.getClass(). Причина в том, что this и this.getClass() - это ссылки на объекты, доступные во всей программе, поэтому любой может синхронизировать эти объекты и тем самым блокировать потоки, которые хотят вызвать ваш метод.

Изменить: Также см. комментарий @Cowan ниже - сводка: если вы действительно хотите заблокировать класс, вы можете использовать synchronized (Worker.class), а не synchronized (this.getClass()), в зависимости от того, какой эффект вы хотите в случае подкласса.

Ответ 2

Нет, синхронизация не будет делать этого. Более конкретно, синхронизация на уровне экземпляра не будет делать этого. Вместо этого вам придется синхронизировать на уровне класса.

Например, вместо того, чтобы:

public synchronized method()
{
    //do stuff
}

Вам нужно будет ввести код:

public void method()
{
    synchronized(this.getClass())
    {
        //do stuff
    }
}

Ответ 3

Нет, если метод static. A synchronized нестатический метод принимает блокировку объекта (экземпляра), на который он вызывается, а не класса.

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

Что вы можете сделать, это создать статический объект-член в своем классе и выполнить синхронизированный блок на этом (класс-глобальном) объекте в вашем методе process.

Ответ 4

Нет, синхронизированный метод блокирует конкретный объект ('this'), поэтому 2 экземпляра одного и того же класса будут блокироваться для разных объектов.

Если вы хотите синхронизировать все экземпляры класса, вам нужно использовать синхронизированный блок IN, блокируя статический конечный объект.

Ответ 5

Если вы сделаете метод process static, он позволит только один вызов метода в одно и то же время.

Если это невозможно, используйте статическую переменную, например Integer lock; И используйте synchronized (lock) внутри вашего метода process. то есть

process()
{
    synchronized (lock)
    {

        // all your code

    }
}

Ответ 6

Я немного не согласен с Aasmund - хотя соглашусь в то же время: Если вы используете такую ​​конструкцию:

class Worker {
...
 public synchronized void process() {...}
}

тогда Aasmund прав - это не будет препятствовать нескольким экземплярам класса Worker выполнять process() параллельно. Однако вы можете использовать ключевое слово synchronized для синхронизации на статическом элементе, чтобы это не происходило:

class Worker {
 static Object o = new Object();
 ...
 public void process() {
  synchronized(o) {
   ...//perform the work here
  }
 }

Ответ 7

Только один поток может удерживать блокировку объекта в любой момент времени.

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

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

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

Примечание. Для статического метода нет "экземпляра", даже если вы можете написать код, который, как представляется, использует экземпляр. например instance.staticMethod()