volatile
是 C# 中一个用于多线程编程的关键字 ,作用是确保变量的可见性 ------ 也就是说,一个线程对变量的修改,其他线程可以马上"看到"。
🔍 为什么需要 volatile
?
在多线程中,CPU 和编译器可能会对代码进行优化,比如:
- 把变量缓存到寄存器或 CPU cache 中;
- 重排指令顺序;
- 延迟同步内存中的变量值。
结果就是:
一个线程改了变量,另一个线程却看不到最新的值。
✅ volatile
的作用
volatile
告诉编译器和 CPU:"这个变量很重要,别给我优化!随时读写内存中的真实值。"
📌 用法语法
csharp
private volatile bool _running = true;
void ThreadMethod()
{
while (_running)
{
// do work
}
}
这样,另一个线程如果设置 _running = false;
,这个线程能立刻感知到,不会卡在死循环中。
🧠 举个例子(不加 volatile 出问题)
csharp
bool running = true;
new Thread(() =>
{
while (running) { }
}).Start();
Thread.Sleep(1000);
running = false; // 👈 这里设置为 false,线程可能 **看不到**!
这段代码可能会卡死,因为 running
被缓存了,线程读取的是老值。
✅ 加上 volatile:
csharp
volatile bool running = true;
new Thread(() =>
{
while (running) { }
}).Start();
Thread.Sleep(1000);
running = false; // 👈 线程立刻感知,安全退出
⚠️ 注意事项
volatile
只能用于字段(field),不能用于局部变量或属性。volatile
只适用于以下类型:bool
byte
,sbyte
short
,ushort
int
,uint
char
float
object
,enum
,IntPtr
,UIntPtr
,long*
,double*
等指针类型
volatile
不等于线程安全,它不保证原子性,只能保证"可见性"。
🧠 总结一句话:
volatile
让你在线程之间正确地观察到变量的变化,适合用于控制标志位(如循环退出),但不适合用于计数器、队列等需要原子操作的场景。