Java 确保变量只设置一次
我需要确保一件物品只卖一次。 这也必须在多个线程上确保 检查Java 确保变量只设置一次,java,exception,thread-safety,Java,Exception,Thread Safety,我需要确保一件物品只卖一次。 这也必须在多个线程上确保 检查buyer变量是否不为空就足够了吗?因此,在我看来,第二个调用方将收到一个AlreadyBoughtException public synchronized void buy(Buyer buyer) throws AlreadyBoughtException { if (this.buyer != null) { throw new AlreadyBoughtException(); } S
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
方法时,没有可能无法购买文章?只要buyer
不能通过非同步方法设置,您的代码就是线程安全的
JVM将确保同步方法不会发生“完全相同的时间”-一个调用方将被视为第一个调用方,而另一个调用方必须等到第一个调用完成后才能继续。只要不能通过非同步方法设置
,您的代码就是线程安全的
JVM将确保同步方法不会发生“完全相同的时间”——一个调用方将被视为第一个调用方,另一个必须等到第一次调用完成后才能继续。您的方法是同步的这一事实使其安全-只要这是您更新买家的唯一方式。您的方法是同步的这一事实使其安全-只要这是您更新买家的唯一方式买方。是的,这很好(当然,除非您是通过其他方法访问买方字段) 两个试图同时执行此方法的线程将无法执行此操作:只有一个线程能够获得锁并初始化买方。然后,另一个线程将执行它,并看到初始化的买方,因为该方法是同步的。是的,这很好(当然,除非您是从另一个方法访问买方字段) 两个试图同时执行此方法的线程将无法执行此操作:只有一个线程能够获得锁并初始化买方。然后,另一个线程将执行它,并查看初始化的买方,因为该方法是同步的。您可以
this.buyer
易变变量您可以
this.buyer
volatile variable您的代码是正确的,但是使用AtomicRefreference可以实现更好的性能和更少的线程争用。我将检查
this.sell==true
。我不明白为什么要让买家复杂化。举个例子,我还尝试了其他方法。您的代码是正确的,但使用AtomicReference可以实现更好的性能和更少的线程争用。我会检查this.sell==true
。我不明白为什么要把买家复杂化。举个例子,我也试过别的东西。两者都做有意义吗?同步setter和使用volatile?不,如果您也是同步的,则不需要volatile,因为volatile所做的一切都是同步的,等等。Volatile在这里也不够,因为你会有几个比赛条件,使用Volatile但不同步实际上是危险的。@Tim B我同意你的观点,如果使用Volatile,就不需要同步(这就是我所说的答案)。但不会有任何竞争条件,因为在函数的第二行中访问了volatile变量。内存障碍将使线程可以获得此文件的最大更新值。你完全错了。需要同步。否则,两个线程都可以检查buyer
是否为空,通过检查,然后都将新值写入buyer
…以允许项目销售两次。同意。因为它设定了买家的价值,这可能会让其他线程站出来并在竞争中领先。两者都做有意义吗?同步setter和使用volatile?不,如果您也是同步的,则不需要volatile,因为volatile所做的一切都是同步的,等等。Volatile在这里也不够,因为你会有几个比赛条件,使用Volatile但不同步实际上是危险的。@Tim B我同意你的观点,如果使用Volatile,就不需要同步(这就是我所说的答案)。但不会有任何竞争条件,因为在函数的第二行中访问了volatile变量。内存障碍将使线程可以获得此文件的最大更新值。你完全错了。需要同步。否则,两个线程都可以检查buyer
是否为空,通过检查,然后都将新值写入buyer
…以允许项目销售两次。同意。因为它设定了买家稍后的价值,这可能会让其他线程站出来,并在比赛中领先。