Skip to content

Is Constructor Thread Safe? What do you think?

Level 2
Several days ago, one of my colleague asked me this question. My first impulse was to answer no, but then I thought that the answer was not obvious. So I wrote a short example and played a little with ILDASM.
Imagine that we have next definition for class CTest
   1: namespace ConsoleApplication1
   2: {
   3:     class CTest
   4:     { 
   5:         public CTest(int i) {}
   6:     }
   7: }

I think that first confusing thing is the usage of the new operator. It may give you a feeling that something here is different. Take a look at the line 7 of this example. What do you think, is this method is thread safe?

   1: class C
   2: {
   3:     private CTest c;
   4:  
   5:     public void Foo()
   6:     {
   7:         c = new CTest(1);
   8:     }
   9: }

This is what happens behind the stage in method Foo(). Here is the Foo() code in a little details

1 .method public hidebysig instance void Foo() cil managed
2 {
3 .maxstack 8
4 L_0000: nop
5 L_0001: ldarg.0
6 L_0002: ldc.i4.1
7 L_0003: newobj instance void ConsoleApplication1.CTest::.ctor(int32)
8 L_0008: stfld class ConsoleApplication1.CTest ConsoleApplication1.CTest::c
9 L_000d: ret
10 }

It is clear that line 7 with opcode newobj creates and pushes a new instance of CTest into the stack and exactly one line later, the local variable c is assigned with a brand new value. If multiple threads were calling CTest::Foo() the result would be unpredictable.

We need to consider one more subtle issue: constructor parameters. If one of the parameters is a reference type, it means that external thread may change the referenced object and make the constructor invalid.

   1: class Test
   2: {
   3:     public Test(IList items)
   4:     {
   5:         if(items.Count > 0)
   6:         {
   7:             // do something special
   8:         }
   9:     }
  10: }


Conclusion:

Constructor is not an exception case then we deal with multi threaded environment. I have no idea why and how this simple issue can confuse anyone but since I witnessed a long discussion regarding this issue, I contribute this post to remove any kind of hesitations. Enjoy.

Post a Comment

Your email is never published nor shared. Required fields are marked *