2016-11-10 10 views
0

Дано:Java SCJP/OCPJP

public class NamedCounter{ 

private final String name; 

private int count; 

public NamedCounter(String name) { this.name = name; } 

public String getName() { return name; } 

public void increment() { count++; } 

public int getCount() { return count; } 

public void reset() { count = 0; } 

} 

Какие три изменения должны быть сделаны, чтобы адаптировать этот класс, чтобы безопасно использовать несколько потоков? (Выберите три.)

A. сброс (объявлять), используя ключевое слово синхронизированного

Б. объявить GetName(), используя ключевое слово синхронизированного

С. объявить GetCount(), используя ключевое слово синхронизированного

Д. объявить конструктор с помощью синхронизированного ключевого слова

Е. объявить приращение(), используя ключевое слово синхронизированного

Ответы: A, C, E. Но я не понимаю, почему. Согласно синхронизированному ключевому слову, используемому только для операций манипуляции. Так зачем отвечать C?

Этот вопрос исходит из свалок SCJP.

+0

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

+0

Приращение переменной не является потокобезопасной. Для этого требуются операции загрузки и хранения, а поток, выполняемый на другом ЦП, может выполнять свою собственную загрузку или хранить в том же месте памяти, перемеженном между этими операциями. – dammina

ответ

0

В JVM используется синхронизированное ключевое слово, чтобы сообщить ему, когда содержимое переменной должно быть видимым в потоках. В опубликованном примере не только метод приращения небезопасен (оператор postincrement выполняет несколько шагов, чтобы действовать, так что другой поток может вмешиваться в него, пока выполняется инкремент), но все методы, которые касаются переменной счетчика - приращение, сброс , и getCount - нужно синхронизованное ключевое слово, чтобы указать, что переменная count может быть изменена в другом потоке. В противном случае JVM может выполнять такие оптимизации, как кеширование значения или полное исключение байт-кода, поскольку он может свободно рассуждать о коде без учета возможности многопоточного доступа.

Существуют альтернативы для синхронизации здесь; например, AtomicInteger тоже будет работать, используя его для подсчета, убедитесь, что значение изменится атомарно и будет доступно таким образом, чтобы оно было видимым для всех потоков. Но поскольку вопрос сформулирован, ответы A, C и E необходимы.

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

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

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

  • Нет связанных вопросов^_^