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

Разница между синхронизацией статического метода и нестационарным методом

В чем разница между синхронизацией статического метода и нестационарным методом в java? Может ли кто-нибудь объяснить пример. Также есть ли разница в синхронизации метода и синхронизации блока кода?

4b9b3361

Ответ 1

Я попытаюсь добавить пример, чтобы сделать это более ясным.

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

Object a = new Object();
Object b = new Object();
...
synchronized(a){
    doStuff();
}
...
synchronized(b){
    doSomeStuff();
}
...
synchronized(a){
    doOtherStuff();
}

В приведенном выше примере поток, выполняющий doOtherStuff(), блокирует другой поток от ввода блока кода, защищающего doStuff(). Однако поток может войти в блок вокруг doSomeStuff() без проблем, поскольку он синхронизируется в Object b, а не Object a.

Когда вы используете синхронизированный модификатор в методе экземпляра (нестатический метод), он очень похож на наличие синхронизированного блока с "this" в качестве аргумента. Итак, в следующем примере методыA() и methodB() будут действовать одинаково:

public synchronized void methodA() {
  doStuff();
}
...
public void methodB() {
    synchronized(this) {
        doStuff();
    }
}

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

Если у вас есть статический метод с синхронизированным модификатором, это практически то же самое, что синхронизировать блок с ClassName.class в качестве аргумента (если у вас есть объект этого класса, ClassName cn = new ClassName();, вы можете получить доступ к этому объект с Class c = cn.getClass();)

class ClassName {
  public void static synchronized staticMethodA() {
    doStaticStuff();
  }
  public static void staticMethodB() {
    synchronized(ClassName.class) {
      doStaticStuff();
    }
  }
  public void nonStaticMethodC() {
    synchronized(this.getClass()) {
      doStuff();
    }
  }
  public static void unSafeStaticMethodD() {
   doStaticStuff();
  }
}

Итак, в приведенном выше примере staticMethodA() и staticMethodB() действуют одинаково. Выполняющий поток также будет заблокирован от доступа к блоку кода в nonStaticMethodC(), поскольку он синхронизируется с одним и тем же объектом.

Однако важно знать, что ничто не остановит поток выполнения от доступа к unSafeStaticMethodD(). Даже если мы говорим, что статический метод "синхронизируется с объектом класса", это не означает, что он синхронизирует все обращения к методам в этом классе. Это просто означает, что он использует объект Class для синхронизации. Небезопасный доступ по-прежнему возможен.

Ответ 2

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

Ответ 3

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

Ответ 4

Практически нет разницы между синхронизацией блока и синхронизацией метода. В основном:

void synchronized m() {...}

совпадает с

void m() { synchronized(this) {...} }

Для сравнения статический синхронизированный метод такой же, как:

static void m() { synchronized(MyClass.class) {...} }

Ответ 5

Чувак, просто намек. Не имеет отношения к вашему вопросу:

Если какой-либо метод * Stuff() делает либо

this.a= /*yet another*/ new Object();

или

this.b= /*yet another*/ new Object();

тогда вы ввернуты. Поскольку блокировка находится внутри значения, а не внутри ссылки. См. синхронизированные ссылки Java

Ответ 6

Java Thread получает блокировку уровня объекта, когда он входит в экземпляр синхронизированного java-метода и получает блокировка уровня класса, когда он входит в статический синхронизированный java-метод . Используя синхронизированный блок, вы можете блокировать критический раздел кода и избегать блокировки всего метода, который может ухудшить производительность.