2013-07-16 5 views
6

Когда член Java должен быть поточно-безопасным, мы делаем так:Как работает статическая синхронизированная функция?

public synchronized void func() { 
    ... 
} 

Этот синтаксис эквивалент:

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

То есть, на самом деле использует this для замка.

Мой вопрос, если я использую synchronized с методом static следующим образом:

class AA { 
    private AA() {} 

    public static synchronized AA getInstance() { 
     static AA obj = new AA(); 
     return obj; 
    } 
} 

В этом случае на то, что замок сделан для метода synchronized?

+0

Класс AA будет заблокирован 'синхронизированные (AA.class)', но ни одного случая –

+3

Не статическое объявление локальной переменной 'obj' синтаксическую ошибку? – Thilo

ответ

13

В случае статического синхронизированного метода, то class объектом вашего class AA будет неявным замок

его эквивалент

class AA { 
    private AA() {} 

    public static AA getInstance() { 
     synchronized(AA.class) { 
      AA obj = new AA(); 
      return obj; 
     } 
    } 
} 
+3

+1. эквивалентно 'synchronized (AA.class) {' – Thilo

+0

, но как насчет 'static AA obj = new AA();' - не будет ли он давать ошибку времени компиляции? – exexzian

+0

да, теперь его штраф – exexzian

7

От section 8.4.3.6 of the JLS:

Синхронное метод приобретает монитор (§17.1) до его выполнения.

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

Таким образом, ваш код приобретает монитор для AA.class. Как sanbhat говорит, это как

synchronized(AA.class) { 
    ... 
} 

... так же, как с помощью метода экземпляра было бы

synchronized(this) { 
    ... 
} 
0

Он работал на замке AA.class.

public static AA getInstance() { 
     synchronized(AA.class){ 
      static AA obj = new AA(); 
      return obj; 
     } 

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