locked
Constructors - are they thread safe?

    Question


  • Is the code that executes within the constructor of a class thread safe?

    I have been given some class code in which instances of the class are created in a multi threaded environment.  The author of the code does quite a bit of initialization in the constructor with no safety measures for thread safety. 

    So either the author knows that it is protected or is just ignorant of the issues.

    Thanks,

    cats
    Tuesday, June 24, 2008 10:16 PM

Answers

  • It's irrelevant whether constructors access shared resources or not, because obviously the thread-safety question is then moved to these other resources.  The question is whether a specific object's constructor is thread-safe, and the answer is generally yes.  A constructor is typically called as part of the execution of a new statement or Activator.CreateInstance, and it operates on a new object that has just been allocated.  That object can't be accessed by other threads until the constructor returns because the reference to it is not available until the constructor returns*.

    However, it is possible to create an uninitialized object (using FormatterServices.GetUninitializedObject) and then call the object's constructor explicitly.  In that case, I believe there is no guarantee that two threads can't call the constructor at the same time (even though it obviously has correctness implications - what would it mean for an object to be constructed twice?).

    * Since CLR memory writes have release semantics, it's guaranteed that the last write within the object's constructor happens before the write that assigns the object's address to the creator's reference to the object.  (This is unlike Java rules, in which final fields only are guaranteed to be assigned.)


    Sasha Goldshtein | http://blogs.microsoft.co.il/blogs/sasha
    • Proposed as answer by Sam Vishwas Wednesday, June 25, 2008 5:56 PM
    • Marked as answer by jack 321 Friday, June 27, 2008 6:19 AM
    Wednesday, June 25, 2008 2:02 PM
  • Hello catsaremyfriends

    It really depends on what you have in those constructors...

    Thank you,
    Sunil Vishwas
    • Proposed as answer by Sam Vishwas Wednesday, June 25, 2008 2:18 AM
    • Marked as answer by jack 321 Friday, June 27, 2008 6:19 AM
    Wednesday, June 25, 2008 12:29 AM
  • As Sunil said, it depends on what you have in your constructor. If constructor access any shared resources without using synchronization contexts, you have thread unsafe code.



    Sincerly, Navaneeth.K.N
    • Proposed as answer by Sam Vishwas Wednesday, June 25, 2008 6:50 AM
    • Marked as answer by jack 321 Friday, June 27, 2008 6:19 AM
    Wednesday, June 25, 2008 6:26 AM
  • Constructors are not implicitly thread safe.  They are just regular old methods as far as execution is concerned.  You need to use the usual thread safety mechanisms if you access any shared resources from within a constructor.
    • Proposed as answer by Sam Vishwas Wednesday, June 25, 2008 6:50 AM
    • Marked as answer by jack 321 Friday, June 27, 2008 6:19 AM
    • Marked as answer by jack 321 Friday, June 27, 2008 6:19 AM
    • Marked as answer by jack 321 Friday, June 27, 2008 6:20 AM
    Wednesday, June 25, 2008 6:27 AM

All replies

  • Hello catsaremyfriends

    It really depends on what you have in those constructors...

    Thank you,
    Sunil Vishwas
    • Proposed as answer by Sam Vishwas Wednesday, June 25, 2008 2:18 AM
    • Marked as answer by jack 321 Friday, June 27, 2008 6:19 AM
    Wednesday, June 25, 2008 12:29 AM
  • As Sunil said, it depends on what you have in your constructor. If constructor access any shared resources without using synchronization contexts, you have thread unsafe code.



    Sincerly, Navaneeth.K.N
    • Proposed as answer by Sam Vishwas Wednesday, June 25, 2008 6:50 AM
    • Marked as answer by jack 321 Friday, June 27, 2008 6:19 AM
    Wednesday, June 25, 2008 6:26 AM
  • Constructors are not implicitly thread safe.  They are just regular old methods as far as execution is concerned.  You need to use the usual thread safety mechanisms if you access any shared resources from within a constructor.
    • Proposed as answer by Sam Vishwas Wednesday, June 25, 2008 6:50 AM
    • Marked as answer by jack 321 Friday, June 27, 2008 6:19 AM
    • Marked as answer by jack 321 Friday, June 27, 2008 6:19 AM
    • Marked as answer by jack 321 Friday, June 27, 2008 6:20 AM
    Wednesday, June 25, 2008 6:27 AM
  • It's irrelevant whether constructors access shared resources or not, because obviously the thread-safety question is then moved to these other resources.  The question is whether a specific object's constructor is thread-safe, and the answer is generally yes.  A constructor is typically called as part of the execution of a new statement or Activator.CreateInstance, and it operates on a new object that has just been allocated.  That object can't be accessed by other threads until the constructor returns because the reference to it is not available until the constructor returns*.

    However, it is possible to create an uninitialized object (using FormatterServices.GetUninitializedObject) and then call the object's constructor explicitly.  In that case, I believe there is no guarantee that two threads can't call the constructor at the same time (even though it obviously has correctness implications - what would it mean for an object to be constructed twice?).

    * Since CLR memory writes have release semantics, it's guaranteed that the last write within the object's constructor happens before the write that assigns the object's address to the creator's reference to the object.  (This is unlike Java rules, in which final fields only are guaranteed to be assigned.)


    Sasha Goldshtein | http://blogs.microsoft.co.il/blogs/sasha
    • Proposed as answer by Sam Vishwas Wednesday, June 25, 2008 5:56 PM
    • Marked as answer by jack 321 Friday, June 27, 2008 6:19 AM
    Wednesday, June 25, 2008 2:02 PM
  • Well, the original post mentioned "quite a bit of initialization" in the ctor and did not specify what kind of initialization.  Yes, any operations on the instance data of the newly constructed object itself will not conflict simply because no one else has a reference to that object at that time, except for the edge case you point out.  But it's easy to imagine the ctor accessing some shared resources during its initializing tasks, and that's not thread-safe.  I wouldn't exactly call that "irrelevant", I'd rather guess it was the real intention of the question...
    Thursday, June 26, 2008 8:09 AM
  • Chris, the only person who knows the real intention of the question is the OP :-)  It's just that constructors aren't special if the question is not about the constructor itself but about the resources accessed by it.  I could just as well ask whether instance methods are thread safe, or properties are thread safe - and my natural inclination is to answer that with regard to instance methods and properties, and not the resources they might access in turn.
    Sasha Goldshtein | http://blogs.microsoft.co.il/blogs/sasha
    Friday, June 27, 2008 9:41 AM