【发布时间】:2017-03-18 05:13:32
【问题描述】:
我有两节课。
一个类只是一个带有 get 和 set 同步方法的整数值的容器。
public class Sync {
private int dataSync;
public synchronized int getDataSync() {
return dataSync;
}
public synchronized void setDataSync(int data) {
dataSync = data;
}
}
其他类类似。 它只是一个带有 get 和 set 方法的整数值的容器,没有同步。
public class NotSync {
private int dataNotSync;
public int getDataNotSync() {
return dataNotSync;
}
public void setDataNotSync(int data) {
dataNotSync = data;
}
}
现在我的问题是“10 值保证对所有其他线程可见”在运行方法结束时。
public class RunSync {
public static void main(String[] args) {
RunSync rs = new RunSync();
rs.run();
}
private NotSync dataNS;
private Sync dataS;
private int data;
public RunSync() {
dataS = new Sync();
dataNS = new NotSync();
}
public synchronized void run() {
data = 100;
dataS.setDataSync(45);
dataNS.setDataNotSync(10);
//Question A: is 10 value guaranteed to be visible to all other
//threads when method exits?
//we are inside a synchronized block aren't we?
//so all writes must be flushed to main memory
}
}
编辑:想象一下还有其他线程。这只是一个快速编写的示例。问题是当同步块完成时,究竟保证什么会刷新回主内存。
EDIT2:根据java内存模型 “只有在某些情况下,才能保证一个线程对字段所做的更改对其他线程可见。一种情况是写入线程释放同步锁,而读取线程随后获取相同的同步锁。
那么如果另一个线程获得了 RunSync 锁,是否可以保证在 RunSync 的 NotSync 实例中看到 10?即使 NotSync 不受保护?
Edit3:没有明确答案的相关问题。我还在寻找。 What is the scope of memory flushed or published to various threads when using volatile and synchronized?
EDIT4:为了简化示例,RunSync 类中的这个方法怎么样
public synchronized void run2() {
dataNS.setDataNotSync(10);
}
run2 退出时,什么都不能保证刷新到主存?一个明确的答案将回答我的问题。如果否,则意味着只有锁的成员才能保证被刷新,并且如果其他线程在 RunSync 上获取相同的锁,其他线程将可以看到该成员。 答案是不保证。
EDIT5:在这种情况下,断言是否保证为真?
public class RunSync {
public volatile boolean was10Written = false;
public synchronized void run2() {
dataNS.setDataNotSync(10);
was10Written = true;
}
public void insideAnotherThread() {
if(was10Written) {
int value = dataNS.getDataNotSync();
assert value == 10;
}
}
}
【问题讨论】:
-
为什么你的问题是反问的?
-
它对其他线程可见,这些线程在读取之前同步某些内容。
-
@Matt Timmermans 修辞,因为这只是一个例子。同步退出时,究竟是什么刷新回主内存?只有锁定成员?不是他们的内容?
-
如果这是一个反问的问题,那么您就不会期望得到答案,那么您一开始就不应该在这里发布它。你到底在问什么?
-
@Mark Rotteveel 哈哈,是的,我的错误.. 对 rethorical 这个词感到困惑。刚刚检查了意思哎呀。只是是或否,并在代码注释中对问题 A 进行简短解释
标签: java multithreading synchronization visibility