1

I wish to atomically increment a static variable and simultaneously assign the new value to an instance field in a lock-free manner. The objective is for each object to get a unique, incrementing id upon creation, such that there is no chance for two objects to get the same id.

Will the following code achieve this?

class MyClass
{
    private static int currentOrderingId;
    private int orderingId;

    public MyClass()
    {
        Interlocked.Exchange(ref orderingId, Interlocked.Increment(ref currentOrderingId));
    }
}
Tudor
  • 61,523
  • 12
  • 102
  • 142
  • 6
    You just need `orderingId = Interlocked.Increment(ref currentOrderingId);` – Matthew Watson Jul 20 '18 at 12:49
  • 1
    @Matthew Watson: Of course, why did I not think of that? :( Please post this in an answer. – Tudor Jul 20 '18 at 12:50
  • 3
    @Tudor the atomicity of the write is irrelevant, since this is the constructor - so the field cannot yet be visible to multiple threads (unless you do bad things like pass out a `this` reference inside the constructor *before* you assign the field) – Marc Gravell Jul 20 '18 at 12:59

1 Answers1

4

You only need to do this:

orderingId = Interlocked.Increment(ref currentOrderingId);

There's no way that two threads could then receive the same value, so it is threadsafe.

Matthew Watson
  • 104,400
  • 10
  • 158
  • 276
  • 1
    @xanatos Actually, for a constructor it is guaranteed that the constructor has run to completion before the reference to the constructed object is assigned to the variable that receives it, so therefore it is not possible for any other thread to observe an uninitialised value of a field. See [this answer](https://stackoverflow.com/a/29147573/106159) for more details. – Matthew Watson Jul 20 '18 at 14:17
  • I removed my comment... But then I did some research... The CLR20 model isn't still implemented in [mono](https://github.com/mono/mono/issues/7313), that still uses the ECMA weak model... And Unity uses Mono... – xanatos Jul 20 '18 at 14:31
  • 1
    @xanatos Ah, good point! So in Unity one would have to be careful about accessing just-created objects from threads other than the creating one. – Matthew Watson Jul 20 '18 at 14:43