C#中Interlocked实现线程安全ID生成:Exchange是否冗余?
关于Interlocked类代码的疑问解答
原代码逻辑
原CreateNextId方法的核心作用是:原子性地获取当前_nextId的旧值,再将_nextId递增1,最终返回这个旧值。比如初始_nextId = 1时,方法返回1,同时_nextId被修改为2。
其中Interlocked.Exchange(ref id, this._nextId)这一行绝非冗余——它是多线程环境下安全获取_nextId当前值的关键:如果不用原子操作,刚读取完_nextId的值,其他线程就可能修改它,导致拿到的旧值不准确。
替换代码的问题
你提供的替换代码:
Interlocked.Increment(ref this._nextId); return _nextId;
无法达到原代码的目的,原因有两点:
- 语义完全改变:原代码返回递增前的旧ID,而这段代码返回的是递增后的新ID。比如初始
_nextId=1,替换代码会返回2,和原代码的返回结果完全相反。 - 存在线程安全漏洞:即便你想返回新ID,直接
return _nextId也不安全——Interlocked.Increment执行完后,其他线程可能立刻再次修改_nextId,导致返回的值不是你刚递增后的结果。正确的写法应该直接用Interlocked.Increment的返回值:
因为return Interlocked.Increment(ref this._nextId);Interlocked.Increment本身会原子性完成递增,并返回递增后的新值,无需后续读取_nextId。
总结
原代码中的Interlocked.Exchange是实现“返回递增前旧ID”逻辑的必要步骤,并非冗余。替换代码既改变了核心语义,又存在线程安全问题,无法替代原代码。
内容的提问来源于stack exchange,提问作者Azeeb
相关产品推荐
相关产品推荐

