Как контролировать доступ к синхронизации между статическим методом и методом экземпляра - PullRequest
3 голосов
/ 07 июня 2011

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

В настоящий момент я не могу найти никакой ситуации в реальной жизни, поэтому я делаю предположение:

Два класса A и B, класс A имеют статические методы с формальным параметромкласса B, и методы экземпляра тоже.Затем я создаю два потока для одновременного выполнения двух методов A.

Сколько способов сохранить состояние ниже obj всегда согласованно?

class B { ... }
class A {
      public synchronized void instanceMethod(B obj){ ... }; 
      public static synchronized void staticMethod(B obj){ ... };

      public static void main(String[] args){
            B obj = new B();
            // create a Thread to modify the state of obj with A's instanceMethod
            // create a Thread to modify the state of obj with A's staticMethod
      }
}

Ответы [ 4 ]

2 голосов
/ 07 июня 2011

Синхронизация по параллельному объекту "B".

public void instanceMethod(B obj) {
    synchronized(obj) {
        //no other thread will enter a synchronized block on 'obj' since we leave it
        ...
        obj.doSomething();
        ...
        obj.doSomethingElse(); //I can trust here that no other thread manipulated 'obj' since 2 lines before.
        ...
    }
}

То же самое для статического метода.

2 голосов
/ 07 июня 2011

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

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

Нет смысла блокировать один объект и изменять несвязанный объект,Если вы собираетесь изменить B, его методы должны быть синхронизированы, и вам может не потребоваться синхронизировать методы на A.

Можете ли вы написать более понятный пример, который будет компилироваться?

class B { 
      public synchronized alter() { };
}
class A {
      public void instanceMethod(B obj){ obj.alter(); }; 
      public static void staticMethod(B obj){ obj.alter(); };

      public static void main(String[] args){
            B obj = new B();
            // create a Thread to modify the state of obj with A's instanceMethod
            // create a Thread to modify the state of obj with A's staticMethod
            obj.alter();
      }
}
1 голос
/ 07 июня 2011

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

class B { ... }
class A {
      static Object myLock = new Object();
      public void instanceMethod(B obj){ synchronized(myLock) {...} }; 
      public static void staticMethod(B obj){ synchronized(myLock) {...} };

      public static void main(String[] args){
            B obj = new B();
            // create a Thread to modify the state of obj with A's instanceMethod
            // create a Thread to modify the state of obj with A's staticMethod
      }
}
0 голосов
/ 07 июня 2011

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

...