[英]If a simple write is done inside a synchronized block , then a read in another synchronized block is consistent?
一个线程写入变量的值,另一个线程读取它,以防两个操作都包含在同步块中,但都定义在不同的对象上,如下所示。
private Object o1 = new Object();
private Object o2 = new Object();
private int x = 0;
...
synchronized(o1){
x = 10;//write (simple atomic write) inside the synchronized block so value is flushed to main memory
}
...
synchronized(o2){
System.out.println(x);// read inside the synchronized block so read from main memory and not from thread cache.
}
Q1。 是否保证read与x的最新值一致?
另一种情况
private Object a = new Object();
private Object b = new Object();
private int p = 0;
...
synchronized(a){
p = p + 1;
}
....
synchronized(b){
System.out.println(p);
}
Q2。 由于p = p+1
不是原子的,因此在这种情况下我们可能会遇到数据不一致的情况。 但是对于Q1。 这种情况下,因为写入是简单且原子的,并且在同步块中完成,因此在这种情况下我们具有一致性。
如果我的理解正确,请帮助我。
Q1。 是否保证read与x的最新值一致?
不,因为它们在不同的事情上是同步的。
在同步块的结束和同一监视器上同步的块的开始之间存在先行关系。
如果监视器不同,则没有这种关系。
您可以在语言规范JLS 17.4.5 (强调我的)中找到它:
从上面的定义可以得出:
- 监视器上的解锁发生在该监视器上的每个后续锁定之前。
- 对 volatile 字段 (§8.3.1.4) 的写入发生在对该字段的每次后续读取之前。
- 在线程上调用 start() 发生在启动线程中的任何操作之前。
- 线程中的所有操作发生在任何其他线程从该线程上的 join() 成功返回之前。
- 任何 object 的默认初始化发生在程序的任何其他操作(默认写入除外)之前。
Q2。 由于 p = p+1 不是原子的,因此在这种情况下我们可能会遇到数据不一致的情况。 但是对于Q1。 这种情况下,因为写入是简单且原子的,并且在同步块中完成,因此在这种情况下我们具有一致性。
你没有一致性。 请参阅问题 1 的答案。
synchronized
块,除了锁定之外,确保内部读取的值是相关的并从主 memory 中获取,甚至在块释放之前,所有更改的数据都会传输到主 memory。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.