我的想法是异步运行一些操作;我可以保证两个操作永远不会同时运行,但我不能保证它们将在与其他操作相同的线程/ CPU上运行。
// Example code
int myValue = 0;
ThreadPool.QueueUserWorkItem(state => {
myValue++;
ThreadPool.QueueUserWorkItem(state2 => {
Console.WriteLine(myValue);
});
});
即使没有锁定,输出仍保证为1
吗?
也许在Thread.MemoryBarrier()
之前需要拨打Console.WriteLine(myValue)
?
或者myValue
可能会成为volatile
?
我不习惯没有锁定的多线程编程,我希望有人可以解决我的疑虑。
谢谢!
修改
如果我决定使用锁定怎么办?此代码是否保证输出1
?
如果是,为什么?编译器无法决定将myValue
存储在CPU的寄存器中吗?
我从来没有遇到像这样的代码有任何问题,但到目前为止我只在x86和x64 CPU上运行我的程序。那么MONO,ARM和其他“深奥”平台呢?
// Example code
object lockMe = new object();
int myValue = 0;
ThreadPool.QueueUserWorkItem(state => {
lock(lockMe) {
myValue++;
}
ThreadPool.QueueUserWorkItem(state2 => {
lock(lockMe) {
Console.WriteLine(myValue);
}
});
});
再次感谢!
答案 0 :(得分:1)
ThreadPool.QueueUserWorkItem
,就像在其他线程中执行代码的任何其他库函数,保证这个代码会看到每个修改,可见当前线程直到函数调用。
由于myValue++
在程序顺序之前位于ThreadPool.QueueUserWorkItem()
,因此调用程序线程会看到值的修改结果。所以Console.WriteLine(myValue)
肯定会看到更新的价值。
在这种情况下,完全没有锁定,易失性修饰符。