2015-12-07 3 views
1

В следующем случае: volatile избыточное? Удаляете ли вы volatile в какой-то степени? В качестве альтернативы, оставив volatile, но удаление синхронизированного блока и синхронизированного модификатора имеет значение здесь?Java volatile необходим с синхронизированным доступом?

private volatile boolean registered; 

synchronized boolean registered() { 
    return registered; 
} 

void setRegistered(boolean registered) { 
    synchronized (this) { 
    this.registered = registered; 
    } 
} 
+0

Не стоит упоминать, что операторы 'synchronized' *, вероятно, не нужны * (если вы не хотите, чтобы эти методы не вызывались в других синхронизированных блоках в другом месте, мы не видим). В этом случае использование 'synchronized' для инкапсуляции переменной' volatile 'нарушает цель 'volatile'. –

ответ

2

Нет, если у вас нет какой-либо другой доступ, что вы не показано, registered прекрасно без volatile.

Удаление volatile ускорит код, когда-либо так слегка, я думаю. Но я думаю, что основное преимущество удаления volatile - это очистка кода для сопровождающего.

В этом случае нет никакой разницы между volatile и синхронизированными методами, которые я могу видеть, поэтому используйте тот или иной. (За исключением, что синхронизированные методы делают объект, который вы используете, чтобы охранять registered поле общественного, который может быть хорошим и плохим. Частный volatile поддерживает синхронизацию блокировки частных.)


Чтобы попытаться выяснить, что Последнее утверждение, если у вас есть класс, как это:

public class Reg { 
    private boolean registered; 

    synchronized boolean registered() { 
     return registered; 
    } 

    void setRegistered(boolean registered) { 
     synchronized (this) { 
     this.registered = registered; 
     } 
    } 
} 

Что вы затем создать новый экземпляр:

public class Test { 
    public static Reg reg; 
    public void static main(String... args) { 
    reg = new Reg(); 
    synchronized(reg) { 
      // do stuff 
    } 
    } 
} 

Любой, кто пытается получить доступ к reg.registered(), пока этот замок в Test удерживается, блокируется до тех пор, пока не будет освобождена блокировка. Блокировка является общедоступной для всех, кто может видеть объект. Это может быть хорошо и плохо. Это позволяет другим классам контролировать доступ к вашим методам, что может быть полезно для атомарности, но оно также может испечь управление потоками в исходной базе, где оно распространяется повсюду, а не просто инкапсулируется одним классом. Хорошо и плохо. Вероятно, есть и другие примеры того, почему это может быть хорошо и плохо, это всего лишь один.

+0

Можете ли вы объяснить, что вы имеете в виду, чтобы сделать объект общедоступным? Вы говорите, что класс «этого» станет общедоступным? –

+0

«если у вас нет другого доступа», включая * внутренний * доступ. Если этот класс затрагивает переменную-член «зарегистрирован» только с помощью представленных методов доступа и мутатора, то их синхронизация защищает эту переменную достаточно, но если ее также можно получить напрямую через другие, несинхронизированные методы экземпляра, то нет. –

+0

@JohnBollinger Правильно, если бы я, возможно, захотел сделать больше с этим классом или «будущим», я мог бы предпочесть 'volatile' над синхронизированными частями. –

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