简体   繁体   English

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

[英]Synchronized property reading as non-synchronized property

I have a non-atomic java property, which can be set by synchronized setter. 我有一个非原子的java属性,可以通过同步的setter来设置。 My question is, can I read this property by non-synchronized getter? 我的问题是,我可以通过非同步的吸气剂读取该属性吗? Thanks. 谢谢。

You can read the property, ie the thread will see some value but the problem is that it is not predictable -- it may not reflect the most recent value written by another thread or it may even be a random value. 您可以读取该属性,即线程将看到一些值,但是问题在于它是不可预测的-它可能无法反映另一个线程写入的最新值,甚至可能是随机值。 Therefore, you should synchronize the getter as well. 因此,您还应该同步吸气剂。 It is not safe to only synchronize methods that write to a variable. 仅同步写入变量的方法是不安全的。

If the property is not atomic, you might have to introduce a ReadwriteLock. 如果该属性不是原子的,则可能必须引入ReadwriteLock。 See http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReadWriteLock.html 参见http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReadWriteLock.html

The answer depends on whether the field is volatile. 答案取决于该字段是否易变。

If the field is not volatile, then the other answers are correct. 如果该字段不是可变的,则其他答案是正确的。 You can read the value, but the thread doing the read many not be able "see" the value that another thread wrote. 您可以读取该值,但是进行读取的线程却无法“看到”另一个线程写入的值。 The value written might be in a thread-local cache, so the second thread might always see the old value. 写入的值可能在线程本地缓存中,因此第二个线程可能总是看到旧值。 In addition, the JIT compiler is free to reorder the code in a way that only works if no one is reading the value concurrently. 另外,JIT编译器可以自由地对代码重新排序,这种方式只有在没有人同时读取该值的情况下才有效。

If the field is volatile, then you will get the behavior you want. 如果该字段是易变的,那么您将获得所需的行为。 The JVM will ensure that every thread will get the latest value. JVM将确保每个线程都将获取最新值。

Note you shouldn't do read-modify-write operations (like incrementing an integer field) on a volatile field outside of a synchronized block, because race conditions can result in unexpected results. 请注意,您不应该在同步块外部的易失字段上执行读-修改-写操作(如递增整数字段),因为竞争条件可能会导致意外结果。

For more details, read Java Concurrency in Practice . 有关更多详细信息,请阅读《 实践中的Java并发》

You can read the value through getter method but you can get unpredictable value. 您可以通过getter方法读取该值,但可以获得无法预测的值。 Because the movement you are getting value from getter it might be possible that other thread call setter method and change the value. 因为您正在从getter获取值,所以其他线程可能会调用setter方法并更改值。 So to avoid data violation we should make setter and getter both synchronize and it must be lock under same object lock. 因此,为避免数据冲突,我们应该使setter和getter都同步,并且必须在同一对象锁下锁定。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM