这段C#代码是否线程安全?如何识别ThreadSafe实现方式?
这段C#代码的线程安全问题解析
先明确:线程安全的核心是多个线程同时访问共享资源时,不会出现意外的、不符合预期的结果。你的判断没错,这段代码确实不是线程安全的,原因如下:
- 共享变量缺乏同步保护:变量
a是主线程和新建线程的共享资源,但代码里没有任何同步机制(比如锁、volatile关键字、原子操作类)来协调两个线程的读写行为。 - 可见性问题:现代CPU有多级缓存机制,新建线程把
a改成3后,这个值可能只存在于它所在CPU的缓存中,主线程的缓存还保留着初始值2。这会导致主线程永远打印2,完全看不到另一个线程的更新。 - 指令重排序风险:编译器或CPU为了优化性能,可能对读写指令进行重排序。在没有同步约束的情况下,写入
a=3的操作和主线程读取a的操作顺序可能被打乱,进一步加剧结果的不确定性。
简单修复示例
比如用volatile关键字保证变量的可见性:
using System.Threading; volatile int a = 2; new Thread(() => { a = 3; }).Start(); for (; ; ) { Console.WriteLine(a); Thread.Sleep(200); }
或者用lock来同步读写:
using System.Threading; int a = 2; object lockObj = new object(); new Thread(() => { lock(lockObj) { a = 3; } }).Start(); for (; ; ) { lock(lockObj) { Console.WriteLine(a); } Thread.Sleep(200); }
内容的提问来源于stack exchange,提问作者KPiotrowski
相关产品推荐
相关产品推荐

