你应该同步访问Java中的属性吗?

这个问题在这里已经有了答案:

  • getter和setter应该同步吗? 4个答案

  • 我的问题是为什么?

    确保跨线程的内存可见性。

    什么是同步getId方法的使用?

    每次同步的getId调用都会保证给定的id在操作结束的时刻是最新的(释放一个锁)。

    或者如果我不同步会发生什么?

    一个陈旧的getId值将被用来更新其他影响正确性的变量。


    每个使用共享状态变量的方法都需要某种同步。 getter提供状态,所以需要同步。 setter改变状态,同步也是必需的。

    设想一个改变id(一个作者)的线程,以及一个读取该id(读者)的线程。 如果这些线程没有通过同一个锁同步它们的操作,当线程同时运行时可能会发生奇怪的事情:

  • 读者在执行过程中读取变量。
  • 读者可以看到部分(或不正确)初始化/设置值。
  • 读者可能已经过时了。

  • Synchronized指定对变量的任何访问都一次仅限于一个线程。 所以它会锁定,以防止他人在完成该功能期间修改它。 你可以在这里看到更多的细节和官方文档:'同步'是什么意思?

    至于什么可能发生,有一个相当简单的例子,但不使用ID,因为它不应该改变。 假设你有一个名为“cost”(名字无关)的属性,其值为10,并且有两个线程可以同时访问该属性。

    该进程不同步:

    流程A - 呼吁将成本更改为20。

    流程B - 打电话来获得成本

    过程B - 获取成本= 10

    过程A - 完成修改成本。

    因此,即使线程A的成本为20,但在B检索其值之前,属性并未更新,从而导致收到错误的信息。


    synchronized关键字有两个作用:

  • 只有一个Thread可以进入给定的方法/代码块。 这对于复杂的计算非常有用。
  • 一个Thread所做的更改将被另一个Thread 看到 。 默认情况下不是这样。 jvm /硬件可能会为某些Threads缓存某些值。 你可以在这里阅读更多。
  • 注意:当且仅当synchronized块引用同一对象时,上述语句才为真。 由于我们正在讨论getter和setter,所以这将是真实的:它们将锁定在同一个对象上。

    所以是的,我们需要使用synchronized getter和setter。 但有一些替代方案:

  • 对于原语我们可以使用volatile关键字,例如private voltaile int sum; 。 对于易失性原语,我们可以使用普通的getters / setters。
  • 对于final原语,我们可以使用普通的setter - 没有getters。 感谢您指出:)
  • 我们可以使用像AtomicIntegerAtomicLongAtomicReference这样的Atomic值,...
  • 链接地址: http://www.djcxy.com/p/40987.html

    上一篇: Should you synchronize access to properties in Java?

    下一篇: Rxjava 2 exception with camera