繁体   English   中英

如果一个简单的写是在一个同步块中完成的,那么在另一个同步块中的读是一致的吗?

[英]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.

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