public class A { private int variableA = 0; public A() { variableA = 1; Thread B = new Thread(new ThreadStart(() => printA())).Start(); } private void printA() { System.Console.WriteLine(variableA); } }
我担心的是,如果保证线程B在不使用volatile的情况下看到变量A值为1?在主线程中,我只在构造函数中为variableA赋值1.之后我没有触及变量A,它只在线程B中使用,因此可能不需要锁定.@H_301_5@
但是,是否保证主线程将刷新其缓存并将variableA内容写入主内存,因此第二个线程可以读取新分配的值?@H_301_5@
另外,是否保证第二个线程将从主存中读取变量A的内容?可能会发生一些编译器优化,并且线程B可以从缓存而不是主内存中读取变量A内容吗?当指令的顺序改变时,可能会发生这种情况.@H_301_5@
当然,将volatile添加到variableA声明将使代码正确.但是,它是否必要?我问,因为我在构造函数中编写了一些非易失性变量初始化的代码,稍后某些Timer线程使用这些变量,我不确定它是否完全正确.@H_301_5@
谢谢,米哈尔@H_301_5@
解决方法
My concern is if it is guaranteed that
the Thread B will see variableA with
value 1 without using volatile?@H_301_5@
在这种情况下……是的.但是,如果您继续在第二个线程中使用variableA,则在第一次读取后没有保证,它将看到更新.@H_301_5@
But,is it guaranteed that the main
thread will flush his cache and write
the variableA contents to the main
memory,so the second thread can read
the newly assigned value?@H_301_5@
是.@H_301_5@
Additionally,is it guaranteed that
the second thread will read the
variableA contents from the main
memory?@H_301_5@
是的,但仅限于第一次阅读.@H_301_5@
For sure,adding volatile to the
variableA declaration will make the
code correct. But,is it neccessary?@H_301_5@
在这个非常具体和狭窄的情况下……没有.但是,通常建议您在这些场景中使用volatile关键字.它不仅会使代码线程安全,因为场景变得更复杂,但它也有助于记录该字段将由多个线程使用的事实,并且您已考虑使用锁定的含义 – 免费策略.@H_301_5@