【发布时间】:2017-04-22 09:06:56
【问题描述】:
让我们考虑以下 Java 中的标准同步:
public class Job {
private Lock lock = new ReentrantLock();
public void work() {
lock.lock();
try {
doLotsOfWork();
} finally {
lock.unlock();
}
}
}
我了解,基于 Javadoc,这相当于 synchronized 块。我很难看到这实际上是如何在较低级别执行的。
Lock 的状态是 volatile,在调用 lock() 时它会执行 volatile 读取,然后在释放时执行 volatile 写入。写入一个对象的状态如何确保doLotsOfWork 的任何指令(可能涉及许多不同的对象)不会乱序执行?
或者想象一下 doLotsOfWork 实际上被 1000 多行代码所取代。显然,编译器无法提前知道锁内某处存在 volatile,因此它需要停止重新排序指令。那么,如何保证 lock/unlock 的发生前发生,即使它是围绕单独对象的易失状态构建的?
【问题讨论】:
-
我在 Lock/ReentrantLock 实现中看不到任何 volatile。你可以在grepcode.com/file_/repository.grepcode.com/java/root/jdk/… 上查看 ReentraltLock 的实现
-
通过它的实现。它没有定义。仅需要。
-
AbstractQueuedSYnchronizer 的状态是一个易变的变量
-
无法保证
doLotsOfWork()中的指令不会在它们之间重新排序。保证不会使用lock()之前和unlock()之后的说明对它们进行重新排序。
标签: java multithreading concurrency locking volatile