2

(I wish I could tag this question for all class-constructing languages implementing threads, but here under Java, C++, C# and Ruby. Not that I am cool with all of these)

I think I have seen statements to this effect (that class constructors are threadsafe) on blog posts/tutorials. I can't trace any direct statements, but many posts and tutorials make the assumption, or do not even mention the problem of threads running on constructors and destructors. Sticking to Java, which has a history and some formal approach to multi-threading,

Javamex

Jankov's tutorials

Oracle tutorials

All these articles/webpages are written in a confident way and contain rounded discussions. They all mention the Java feature of method synchronization, so you would hope they might mention how this would affect the special methods of construction and destruction. But they do not.

But class constructors and destructors need to be considered like any class methods. Here is an article on Java,

Safe construction techniques in Java

about leaking 'this' references from constructors. And here are a couple of StackOverflow posts,

Incompletely constructed objects in Java,

Java constructor needs locking

showing constructors with thread issues. I doubt threading issues in special methods are limited to Java.

So, I'm wondering,

  • Is the assumption of threadsafety (however defined) based on the general layout of constructors? A tightly coded constructor with not much code would be close to re-entrant code (accepting data through parameters, etc.)

  • Or do interpreters/compilers handle constructors/destructors with special treatment or protections? For example, the Java memory model makes some comments on expectations at the end of construction, and I expect other language specifications will too.

Wikipedia on constructors has little on this. In a different context this post Constructors in Programming languages contains some hints, but is not about threadsafety.

While there many be information in specialist books, it would be good to have general (though language-specific mentions are interesting!) explanations/discussion on StackOverflow.

Community
  • 1
  • 1
  • 1
    Constructors in Java are not thread safe by default. You need to use appropriate techniques to make them thread safe. – assylias Jan 01 '14 at 12:15
  • I think the same applies for [tag:c++], and may be even [tag:c#] ... – πάντα ῥεῖ Jan 01 '14 at 12:17
  • Can you support your claim (that constructors are often regarded as thread safe) with some hard evidence? It sounds ludricous to me. Of course, if you construct a global object and then use its constant methods on different threads, all is fine -- perhaps this was the situation envisaged in those *blog posts/tutorials*? – Walter Jan 01 '14 at 12:36
  • 1
    thread safety is definitely not an intrinsic feature of constructors. It is a common incidental feature. – RichardPlunkett Jan 01 '14 at 12:52
  • Yes fair enough, as I provided no direct link. I wished the title of this post to be an accurate and well-formed question. I do believe I have seen the title statement of this post as an assertion on website material. Question editied with some examples. – Rob Crowther Jan 02 '14 at 18:05

3 Answers3

5

In general local variables which do not point to shared data are thread safe. As you are only creating an object in one thread normally, it is effectively a thread local data structure and thus thread safe (mostly).

In Java, you can break this assumption in a number of ways which include

  • starting a new thread in a constructor
  • setting a reference to the object which is visible to another thread.
  • using non-final fields and adding the object to a thread unsafe container or shared data structure.

Normally these actions are all considered bad practice, so if you avoid these, you have a thread safe constructor without the need for locking.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • 1
    I suspect you need to add "accessing any form of global data" (or maybe static storage duration data) to that list. Accessing global/file/class/static variables is a very common way to lose your thread safety. – RichardPlunkett Jan 01 '14 at 12:56
3

I think the original question is based on some misunderstanding. Constructors are not considered threadsafe.

If the constructor is affecting anything outside of the object itself, then it is not threadsafe, just like any other member functions of the class.

I think the basis on this is based on a constructor that doesn't affect anything other than the object contents (and there are no static member variables), then it's threadsafe based on the fact that there is nothing outside of the object itself that is affected - and until the constructor has finished, nothing else knows that the object exists, so there is no possibility for another thread to "use" the object. But this fails as soon as some global state (any global/static variable, I/O, etc) gets involved, and at that point, thread safety depends on proper locking (of some sort).

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
  • "Outside the class itself" should be "outside the object itself", access to class variables is not by default thread safe. – RichardPlunkett Jan 01 '14 at 12:51
  • Well explained, and more expansive than my own comments - I suspect that idiom and "good practice" accounts for what might be better stated as "constructor code can *usually* be regarded as threadsafe". – Rob Crowther Jan 02 '14 at 18:01
1

Example of Java constructor thread-safety problem is Double Checked Locking pattern, see http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html. In other words

X x = new X();

is always safe, but

X x;  <-- field

x = new X(); <- in a method

is not necessarily safe

Evgeniy Dorofeev
  • 133,369
  • 30
  • 199
  • 275
  • A cleaner example than "Java constructor needs locking" - showing how partial execution/thread switch errors can happen as easily in a constructor as any other method. – Rob Crowther Jan 02 '14 at 18:22