我对java中的内存模型感到困惑,示例如下:
/**
* one thread write request and wait for response
*/
public AbstractPacket writeMessageAndWaitForResp(AbstractPacket packet, int waitTimeoutInSecond) {
if (!(packet instanceof SendToRouter)) {
throw new IllegalArgumentException("this msg can not be sent to router!");
}
int command = packet.getResponseCommand();
AbstractPacket[] slot = new AbstractPacket[]{NullPacket.NULL};
synchronized (("" + this.getFactoryId() + this.getRouterNo() + command).intern()) {// prevent same command request re-entry
command2RespMap.put(command, slot);
synchronized (slot) { // prevent notify before wait
ChannelFuture future = writeMessage(packet);
if (future == null) {
command2RespMap.remove(command);
return null;
}
try {
slot.wait(waitTimeoutInSecond * 1000);
} catch (InterruptedException e) {
logger.error(e.getMessage(), e);
}
}
command2RespMap.remove(command);
}
AbstractPacket result = slot[0]; // get out the result outof slot array
if (result == NullPacket.NULL) {
logger.error("receive sync message timeout!");
return null;
}
return result;
}
/**
* another thread write response and notify the waiter
*/
public void routerResponse(AbstractPacket packet) {
int command = packet.getHeadCommand();
AtomicReference<AbstractPacket> slot = command2RespMap.get(command);
if (slot == null || slot.get() != NullPacket.NULL) {
logger.error("command : {} request not exist !", command);
return;
}
synchronized (slot) {
slot[0] = packet;
slot.notify();
}
}我的问题是,在第一个函数中,我从slot变量上的synchronized块中的索引0中获得了结果。
这是否意味着插槽可能不包含由另一个线程中的第二个函数设置的值?
非常感谢!
发布于 2015-01-05 10:17:47
synchronized关键字作为记忆屏障,可以保证两件事
因此,由于您引用的是同步块外部的插槽,因此不能保证此引用与您在同步块内更新的值一致,也不能保证它是线程本地缓存值还是来自主内存的值。
顺便说一句,正如@chrylis所提到的,你的代码块是非常昂贵的,你至少需要考虑把wait()移出。
https://stackoverflow.com/questions/27772492
复制相似问题