2010-12-09 1 views
4

Я сомневаюсь, что нам нужно сделать статические методы синхронизированными, если он вызывается в синхронном нестационарном методе?Нужно ли создавать статические методы как синхронизированные, если он вызывается в синхронном нестационарном методе?

, например.

class Test 
{ 

     public static void m2() 
     { 


     } 

     public synchronized void m1() 
     { 

      Test.m2(); 
      ---- 
      ---- 
     } 

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

}

ответ

7

Это зависит от того, что делает ваш статический метод. Вам действительно нужна синхронизация? Получает ли доступ к общему изменяемому состоянию?

Если да, то вы, вероятно, сделать необходимость синхронизации (хотя я бы не сделать это только с модификатором synchronized - Я бы создать частную статическую конечную переменную с объектом, чтобы привязываться.)

Тот факт, что ваш метод экземпляра синхронизирован, означает, что ни один из двух потоков не будет выполнять его с тем же целевым объектом - но два потока могут выполняться m1 с различными объектами, поэтому m2 можно было бы вызывать дважды в одно и то же время , Является ли это проблемой или нет, зависит от того, что она делает. Если он не использует какое-либо общее состояние (например, он просто вычисляет что-то на основе его параметров), то его вообще не нужно синхронизировать.

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

+1

У меня есть проблема с вашим последним абзацем. Кодирующие объекты, ссылающиеся на статику, должны быть потокобезопасными, хотя обычно это не делается. Почти все статические методы не должны мутировать статику, и поэтому не должны быть потокобезопасными. Например, вы бы не делали thread-safe `Collections.sort` потоком. – 2010-12-09 10:12:28

0

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

private static final List<Object> GLOBAL_STATE = new ArrayList<Object>(); 

public static synchronized void add(Object foo) { 
    GLOBAL_STATE.add(foo); 
} 

Но в вашем случае вы вызываете метод из другого уже синхронизированного метода. Поэтому вам не нужно синхронизировать его. Но в вашем примере вы делаете свой static метод public. Если это было предназначено, сделайте также synchronized.

2

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

Смежные вопросы