Почему `synchronized` был запрещен для переменных? - PullRequest
2 голосов
/ 15 февраля 2012

Это очень простой вопрос, но я не могу понять идею:

Почему synchronized нельзя назначить переменным Java?

Это может бытьтолько для методов и блоков.Я лично думаю, что это было бы очень аккуратным дополнением к языку программирования Java.

Ответы [ 4 ]

1 голос
/ 15 февраля 2012

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

Первое: требование для монитора объекта означает, что синхронизированное поле не может быть примитивного типа.

Второе: что должен делать синхронизированный на поле?

Есть два возможных ответа:

  • защита доступа к самой ссылке XOR
  • защищает доступ к объекту за ссылкой.

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

Второй вариант: см. Этот кусок кода:

public class Foo {
     public synchronized StringBuilder sb = ...;
     public void doSomething1(){
         StringBuilder sb = this.sb;
         sb.append("foo");
     }

     public void doSomething2(){
         this.sb.append("foo");
     }
}

Так как только доступ будет защищен, оба метода работают одинаково. Первая версия просто проясняет, что сам вызов append не защищен.

О, я забыл: в обоих случаях вы могли бы использовать только взаимное исключение синхронизированных - вещи wait или notify были бы недоступны - потому что вы не можете присоединить какой-либо фрагмент кода к переменной.

Что осталось:

Возможно просто ярлык для AtomicReference?

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

1 голос
/ 15 февраля 2012

для этого есть ключевое слово volatile .

0 голосов
/ 15 февраля 2012

Если вы ищете поля, которые действуют атомарно, попробуйте классы java.util.concurrent.atomic.Например, AtomicInteger позволяет вам добавлять к нему числа атомарно.Если распределение объектов вызывает беспокойство, и вы уверены, что оно вам нужно, AtomicIntegerFieldUpdater<T> (и тому подобное) может дать вам атомный доступ к полям volatile - но вы должны быть осторожны с этим, потому что это легкосломайте ваш код с таким подходом.

0 голосов
/ 15 февраля 2012

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

...