private InstrumentInfo[] instrumentInfos = new InstrumentInfo[Constants.MAX_INSTRUMENTS_NUMBER_IN_SYSTEM];
public void SetInstrumentInfo(Instrument instrument, InstrumentInfo info)
{
if (instrument == null || info == null)
{
return;
}
instrumentInfos[instrument.Id] = info; // need to make it visible to other threads!
}
public InstrumentInfo GetInstrumentInfo(Instrument instrument)
{
return instrumentInfos[instrument.Id]; // need to obtain fresh value!
}
SetInstrumentInfo
并GetInstrumentInfo
从不同的线程调用。
InstrumentInfo
是不可变的类。打电话时我能保证有最新的副本GetInstrumentInfo
吗?恐怕我会收到“缓存”副本。我应该添加某种同步吗?
声明instrumentInfos
为volatile
无济于事,因为我需要将数组项声明为volatile
,而不是数组本身。
我的代码有问题吗?如果有,如何解决?
UPD1:
我需要我的代码在现实生活中工作,而不是符合所有规范!因此,如果我的代码在现实生活中有效,但在某些环境下的某些计算机上“理论上”不能工作 - 那没关系!
- 我需要我的代码在 Windows 下使用最新的 .NET 框架在现代 X64 服务器(当前为 2 个处理器 HP DL360p Gen8)上工作。
- 我不需要在奇怪的计算机或 Mono 或其他任何东西下工作我的代码
- 我不想引入延迟,因为这是 HFT 软件。因此,“微软的实现使用强大的内存模型进行写入。这意味着写入被视为易失性”,我可能不需要添加额外的
Thread.MemoryBarrier
内容,这只会增加延迟。我认为我们可以相信微软将在未来的版本中继续使用“强内存模型”。至少微软不太可能改变内存模型。所以让我们假设它不会。
UPD2:
最近的建议是使用Thread.MemoryBarrier();
. 现在我不明白我必须在哪里插入它才能使我的程序在标准配置(x64、Windows、Microsoft .NET 4.0)上运行。请记住,我不想插入“只是为了在 IA64 或 .NET 10.0 上启动您的程序”的行。速度对我来说比便携性更重要。然而,如何更新我的代码以便它可以在任何计算机上工作也会很有趣。
UPD3
.NET 4.5 解决方案:
public void SetInstrumentInfo(Instrument instrument, InstrumentInfo info)
{
if (instrument == null || info == null)
{
return;
}
Volatile.Write(ref instrumentInfos[instrument.Id], info);
}
public InstrumentInfo GetInstrumentInfo(Instrument instrument)
{
InstrumentInfo result = Volatile.Read(ref instrumentInfos[instrument.Id]);
return result;
}