2012-03-12 3 views
2

, если у меня есть геттер, который имеет только один оператор вроде этогоСинхронизация по одному заявлению?

public class NumberClass{ 
    int number; 

    public int getNumber() { 
     return number; 
    } 
    ... 
} 

и несколько потоков этого метода, я должен синхронизировать этот метод или нет необходимости, так как у него есть только одно заявление ??

ответ

7

Мне нужно синхронизировать этот метод [get] или он не нужен, поскольку он имеет только одно утверждение ??

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

Если поле number было обновлено в thread1, то thread2 может получить либо исходное значение, либо новое значение в зависимости от синхронизации синхронизации. Чтобы иметь значение, опубликованное соответствующим образом, как набор, так и метод получения должны synchronized.

Если вы просто пытаетесь поделиться int значение, то маркировка на number поле как volatile будет работать или с помощью AtomicInteger разделить значение между несколькими потоками надежно может быть более подходящим.

private volatile int number; 

или использование:

private AtomicInteger number = new AtomicInteger(); 
+0

У меня также есть аналогичный вопрос, связанный с синхронизацией [здесь] (https://stackoverflow.com/questions/47783712/do-not-share-same-socket-between-two-threads-at-the-same-time /), где я использую синхронизацию на объекте сокета, и я пытаюсь выяснить, могу ли я вообще избавиться от синхронизации или каким-то другим эффективным способом? Хотел посмотреть, сможете ли вы помочь. – john

+0

Он сделал @DavidSchwartz. В комментарии есть ссылка на его вопрос. – Gray

4

Да, это может быть хорошей идеей, чтобы синхронизировать это заявление. Причина в том, что каждый поток, согласно спецификации, разрешил кэшу собственную версию переменной. Чтобы продемонстрировать это, взгляните на this answer.

Другие варианты для

  • Сделать переменную летучий:

    volatile int number; 
    
  • или использовать AtomicInteger из пакета java.util.concurrent:

    AtomicInteger number; 
    

В качестве побочного примечания: Если number был типа long, даже не чтения переменного были бы атомными (один поток может переписать значение переменного в средней ридовского) , См. Chapter 17.7: Non-atomic Treatment of double and long Спецификации языка Java.

1

Вам необходим защитный барьер памяти, или другие потоки не гарантированно будут видеть «правильное» значение (что означает любое значение, которое явно назначено number).

Чтобы это исправить, объявить number как член final или volatile, или доступ к нему из synchronized блока.

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

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