java synchronized方法 - 它是如何工作的

时间:2013-01-09 18:17:52

标签: java synchronized

我想我知道这一点,但希望确认一下。

显然,synchronized会阻止其他线程访问它,但是我看到了很多例子,例如

   public synchronized void setValue(int value)
   {
       balance=value;
   }

我是否正确地思考,如果该方法只执行如上所述的一行,那么它就没有意义同步。

由于

4 个答案:

答案 0 :(得分:17)

  

我是否正确地思考,如果该方法只执行如上所述的一行,那么它就没有意义同步。

没有。你似乎相信同步只意味着原子性。

但它确实提供了更多 - 特别是,它保证:

  • 原子性,对一行分配无用(下面的边框除外)
  • 能见度
  • 阻止重新排序
  • 互斥:在同一台显示器上同步的2个方法无法同时运行

在您的示例中,如果没有synchronized,则无法保证如果某个线程调用您的方法而另一个线程随后读取balance,则该第二个线程将看到更新的值。

请注意,必须确保两端的可见性:写入和读取需要与同一监视器同步。因此,getter getBalance也需要同步化。

边境案例double and long assignements are not guaranteed to be atomic。因此,即使在如下所示的单行示例中,如果没有synchronized关键字,也有可能一个线程更新double的前32位而另一个线程更新最后32位,从而创建一个新的混合平衡变量。

public synchronized void setValue(double value) {
    balance = value;
}

答案 1 :(得分:2)

它不仅阻止访问此方法的其他线程:它阻止其他线程访问具有相同锁定的任何块或方法(此处为实例)。

关键是如果另一个同步方法更长,你可以放心,这个方法不会同时运行。

如果另一个方法依赖于balance变量在执行期间不变化,这很重要。

答案 2 :(得分:1)

同步方法有两件事:

  • 不允许超过1个线程执行该方法
  • 将线程内存缓存与共享内存同步。

在您的情况下,只有一个线程能够更新该变量,并且所有其他线程也将在变量balance中查看最新数据。

如果没有同步,其他线程会使用(很可能)它们的缓存值balance,因此在程序执行后你会得到不一致的balance值。

您可以在presentation中找到对问题的非常好的解释。

答案 3 :(得分:0)

多个线程可以使用不同的值调用setValue方法。因此,如果您确实希望确保一个线程更改对另一个线程可见,则应该同步该方法。