2014-01-16 3 views
1

Мне нужно убедиться, что изделие продается только один раз. Это должно быть обеспечено также для нескольких потоков.Убедитесь, что переменная установлена ​​только один раз

Достаточно ли проверить, нет ли переменной buyer? Так, на мой взгляд, второй вызывающий абонент получит AlreadyBoughtException?

public synchronized void buy(Buyer buyer) throws AlreadyBoughtException { 
    if (this.buyer != null) { 
     throw new AlreadyBoughtException(); 
    } 

    System.out.println(buyer + " bought article " + identifier); 

    this.buyer = buyer; 
    this.sold = true; 
} 

Это поточно-и я могу предположить, что нет никаких шансов, что эта статья не может быть куплен, когда метод buy вызывается в то же время (точно то же время)?

+1

Ваш код правильный, но с AtomicRefference вы можете достичь более высокой производительности и меньше потоков раздор. – Mikhail

+0

Я бы проверил 'this.sold == true'. Я не понимаю, почему усложнять покупатель. – Ron

+0

Просто пример, попробовал что-то еще. – mhmpl

ответ

2

Тот факт, что ваш метод синхронизирован, делает его безопасным - пока это единственный способ, которым вы когда-либо обновляете покупателя.

5

Пока buyer не может быть установлен с помощью несинхронизированного метода, ваш код является потокобезопасным.

JVM гарантирует, что для синхронизированного метода никогда не произойдет «точно такое же время» - один из вызывающих абонентов будет считаться первым, а другой должен будет дождаться завершения первого вызова перед продолжением.

2

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

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

0

Вы можете

this.buyer 

летучий переменная

+0

Имеет смысл делать то и другое? Синхронизированный сеттер и использование изменчивого? – mhmpl

+1

Нет, волатильность не требуется, если вы также синхронизированы как синхронизированный, делает все неустойчивое и много. Волатильности также будет недостаточно, так как у вас будет несколько условий гонки, на самом деле было бы опасно иметь летучие, но не синхронизированные. –

+0

@Tim B Я согласен с вами, синхронизация не нужна, если используется volatile (вот что я имел в виду под ответом). Но не всегда будет какое-либо условие гонки, когда во второй строке функции будет доступна изменчивая переменная. И барьеры памяти сделают максимально возможное обновление this.buyer доступным для потоков. –

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