|ZYCWPF| 今天看多线程的,但是对volatile这个关键字不理解,怎么感觉用static不是也是一样的效果吗?
大家帮我说说static和volatile的区别
static我清楚是做什么用的
但volatile什么时候用呢?
谢谢
------最佳解决方案--------------------volatile修饰的变量无需lock就可以在多线程内共享,它可以有效保证在多个cpu下更新而刷新各自的缓存。volatile的性能更高,它底层会使用cpu的自旋锁指令。
------其他解决方案--------------------volatile表示数据字段可能被其它线程修改。
比如拿msdn上的例子来说:
public class Worker
{
private volatile bool _shouldStop;
public void DoWork()
{
while (!_shouldStop)
{
Console.WriteLine("Worker thread: working...");
}
Console.WriteLine("Worker thread: terminating gracefully.");
}
}
如果_shouldStop不声明为volatile,编译器优化时就可能省去这个!_shouldStop检查判断,因为它的值始终应该是进行方法时候的那个值,但是加了volatile就不会做这样的优化,循环每次都会去检查,因为它可能被其它线程修改。
------其他解决方案--------------------
public class Worker
{
//private volatile bool _shouldStop;
//上面这语句我感觉改为效果也是一样的啊?所以我看不出作用!谢谢
public static bool _shouldStop;
public void DoWork()
{
while (!_shouldStop)
{
Console.WriteLine("Worker thread: working...");
}
Console.WriteLine("Worker thread: terminating gracefully.");
}
}
------其他解决方案--------------------本帖最后由 caozhy 于 2012-12-04 22:51:17 编辑
多线程程序不要用简单的运行来看效果。你需要在多cpu环境下,反复、大量运行多个线程的程序,并且大量访问共享变量,才能看出来。
不用volatile的话
可能出现如下情况:
如下代码:
_shouldStop = true;
_shouldStop = !_shouldStop;
编译器会转变成这样的代码:
_shouldStop = true;
bool temp = _shouldStop;
temp = !temp; ... 3
_shouldStop = temp;
但是有可能在第三行,这个线程切换了
另一个线程更改了_shouldStop,比如设置为false
但是这个线程再切换的时候不知道,于是将false又写回去了。
------其他解决方案--------------------看一下这个帖子:
http://stackoverflow.com/questions/133270/illustrating-usage-of-the-volatile-keyword-in-c-sharp/1284007#1284007
我用它的代码也试了,打开优化或release模式下,程序死循环。
msdn自带的例子却产生不了这样的现象,按上面帖子里的解释是编译器越来越聪明,会尽量找出这种可能导致错误的优化而不做优化。