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

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。这种情况下,因为写入是简单且原子的,并且在同步块中完成,因此在这种情况下我们具有一致性。

如果我的理解正确,请帮助我。

synchronized块,除了加锁之外,确保里面读取的值是相关的,并且是从主存中取出的,甚至在块被释放之前,所有改变的数据都会被传输到主内存。

Q1. Is it guaranteed that read is consistent with the latest value of x ?

不,因为它们在不同的事情上是同步的。

同步块的结束和同一监视器上同步的块的开始之间存在先行关系。

显示器不同则无此关系

您可以在语言规范中找到它 JLS 17.4.5(强调我的):

It follows from the above definitions that:

  • An unlock on a monitor happens-before every subsequent lock on that monitor.
  • A write to a volatile field (§8.3.1.4) happens-before every subsequent read of that field.
  • A call to start() on a thread happens-before any actions in the started thread.
  • All actions in a thread happen-before any other thread successfully returns from a join() on that thread.
  • The default initialization of any object happens-before any other actions (other than default-writes) of a program.

Q2. As the p = p+1 is not atomic hence we may have data inconsistencies in this case. But for the Q1. case as the write is simple and atomic an done in synchronized block hence in that case we have consistency.

你没有一致性。请参阅问题 1 的答案。