你应该同步访问Java中的属性吗?
这个问题在这里已经有了答案:
我的问题是为什么?
确保跨线程的内存可见性。
什么是同步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。 感谢您指出:) AtomicInteger
, AtomicLong
和AtomicReference
这样的Atomic
值,...