同步属性读取为非同步属性

时间:2015-03-07 13:57:51

标签: java multithreading synchronized

我有一个非原子java属性,可以通过synchronized setter设置。我的问题是,我可以通过非同步的getter读取这个属性吗?感谢。

4 个答案:

答案 0 :(得分:3)

你可以读取属性,即线程会看到一些值,但问题是它不可预测 - 它可能无法反映另一个线程写入的最新值,甚至可能是随机值。因此,您也应该同步getter。仅同步写入变量的方法是不安全的。

答案 1 :(得分:2)

如果属性不是原子属性,则可能必须引入ReadwriteLock。 见http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReadWriteLock.html

答案 2 :(得分:2)

答案取决于该领域是否不稳定。

如果字段不易变,那么其他答案都是正确的。您可以读取该值,但执行读取的线程不能“看到”另一个线程写入的值。写入的值可能位于线程本地缓存中,因此第二个线程可能始终看到旧值。此外,JIT编译器可以自由地重新排序代码,只有在没有人同时读取值的情况下才能正常工作。

如果该字段是易变的,那么您将获得所需的行为。 JVM将确保每个线程都获得最新值。

请注意,不应在同步块之外的易失性字段上执行读取 - 修改 - 写入操作(如递增整数字段),因为竞争条件可能会导致意外结果。

有关详细信息,请阅读Java Concurrency in Practice

答案 3 :(得分:0)

您可以通过getter方法读取值,但是您可以获得不可预测的值。 因为您从getter获取值的移动可能是其他线程调用setter方法并更改值。因此,为避免数据违规,我们应该使setter和getter都同步,并且必须在同一个对象锁定下锁定。