[英]Thread safe id generation with Interlocked in c#
I am trying to understand Interlocked
in C# in thread synchronization.我试图在线程同步中了解Interlocked
in C#。
public int MethodUsedByMultipleThreads()
{
var id = CreateNextId();
return id;
}
private long CreateNextId()
{
long id = 0;
Interlocked.Exchange(ref id , this._nextId);
Interlocked.Increment(ref this._nextId);
return id;
}
Is the line是线
Interlocked.Exchange(ref id , this._nextId);
redundant if I directly use如果我直接使用是多余的
Interlocked.Increment(ref this._nextId);
return _nextId;
Will it serve the same purpose?它会起到同样的作用吗?
The line线
Interlocked.Exchange(ref id, this._nextId);
is both redundant and incorrect.既多余又不正确。 It is redundant because it is practically the same as:它是多余的,因为它实际上与以下内容相同:
id = this._nextId
...because the id
is a local variable that is not shared with other threads. ...因为id
是一个不与其他线程共享的局部变量。 And it is incorrect because there is a race condition between incrementing the _nextId
field and returning it from the method CreateNextId()
.这是不正确的,因为在递增_nextId
字段和从方法CreateNextId()
返回它之间存在竞争条件。 The correct implementation is:正确的实现是:
private long CreateNextId()
{
long id;
id = Interlocked.Increment(ref this._nextId) - 1;
return id;
}
...or simply: ...或者简单地说:
private long CreateNextId() => Interlocked.Increment(ref this._nextId) - 1;
The method Interlocked.Increment
increments the _nextId
field, and returns the incremented value as an atomic operation. Interlocked.Increment
方法递增_nextId
字段,并将递增的值作为原子操作返回。
The subtraction - 1
is there to preserve the semantics of your existing code, regarding the meaning of the field _nextId
.减法- 1
是为了保留现有代码的语义,关于字段_nextId
的含义。 It might be preferable to change its name to _lastId
or _idSeed
, so that the - 1
can be removed.最好将其名称更改为_lastId
或_idSeed
,以便可以删除- 1
。
long CreateNextId() => Interlocked.Increment(ref this._nextId);
This is all you need to generate sequential IDs in a thread-safe manner.这就是以线程安全的方式生成顺序 ID 所需的全部内容。
Do not use _nextId
directly in any way: return _nextId
is a mistake and will yield unpredictable results in a multithreaded environment - the value might be incremented by other threads after your call to Increment
in the current thread.不要以任何方式直接使用_nextId
: return _nextId
是错误的,在多线程环境中会产生不可预知的结果——在当前线程中调用Increment
后,该值可能会被其他线程递增。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.