我对同步块毫无疑问。在我提出问题之前,我想分享另一篇相关帖子的答案链接以回答相关问题。我从同一个答案中引用彼得劳里的话。
同步可确保您拥有一致的数据视图。这意味着您将读取最新值,而其他缓存将获得最新值。缓存足够聪明,可以通过特殊的总线相互通信(JLS 不需要,但允许)这种总线意味着它不必接触主内存即可获得一致的视图。
如果只使用同步,则不需要 volatile。如果您有一个非常简单的操作,而同步操作会过大,那么 Volatile 很有用。
参考上面我有以下三个问题:
Q1。假设在多线程应用程序中有一个对象或原始实例字段仅在同步块中读取(写入可能发生在其他一些没有同步的方法中)。同步块也定义在其他一些对象上。将其声明为 volatile(即使仅在 Synchronized 块中读取)是否有意义?
Q2。我了解已完成同步的对象状态的值是一致的。我不确定在 Synchronized 块中读取的其他对象和原始字段的状态。假设在没有获得锁的情况下进行了更改,但是通过获得锁来完成读取。同步块内所有对象的状态和所有原始字段的值是否始终具有一致的视图。?
Q3。[更新]:无论我们锁定什么,在同步块中读取的所有字段都将从主内存中读取吗?[CKing回答]
我为上述问题准备了参考代码。
public class Test {
private SomeClass someObj;
private boolean isSomeFlag;
private Object lock = new Object();
public SomeClass getObject() {
return someObj;
}
public void setObject(SomeClass someObj) {
this.someObj = someObj;
}
public void executeSomeProcess(){
//some process...
}
// synchronized block is on a private someObj lock.
// inside the lock method does the value of isSomeFlag and state of someObj remain consistent?
public void someMethod(){
synchronized (lock) {
while(isSomeFlag){
executeSomeProcess();
}
if(someObj.isLogicToBePerformed()){
someObj.performSomeLogic();
}
}
}
// this is method without synchronization.
public void setSomeFlag(boolean isSomeFlag) {
this.isSomeFlag = isSomeFlag;
}
}