views:

389

answers:

4

I was reading some of the concurrency patterns in Brian Goetze's Java Concurrency in Practice and got confused over when is the right time to make the code thread safe.

I normally write code that's meant to run in a single thread so I do not worry too much about thread safety and synchronization etc. However, there always exists a possibility that the same code may be re-used sometime later in a multi-threaded environment.

So my question is, when should one start thinking about thread safety? Should I assume the worst at the onset and always write thread-safe code from the beginning or should I revisit the code and modify for thread safety if such a need arises later ?

Are there some concurrency patterns/anti-patterns that I must always be aware of even while writing single-threaded applications so that my code doesn't break if it's later used in a multi-threaded environment ?

+12  A: 

You should think about thread safety when your code will be used in a multithreaded environment. There is no point in tackling the complexity if it will only be run in a singlethreaded environment.

That being said, there are simple things you can do that are good practices anyway and will help with multithreading:

  1. As Josh Bloch says, Favor Immutability. Immutable classes are threadsafe almost by definition;
  2. Only use data members or static variables where required rather than a convenience.
cletus
+1. Additionally, thread-safety generally comes with a performance penalty. I generally try to document classes that are thread-unsafe when they're sharing a package with other classes that ARE largely thread-safe, so that the exceptions to the norm are obvious.
Mike Daniels
How does number 2. improve thread safety
hhafez
If a function is called by two threads and they use shared state then contention is an issue. If however the only state they rely upon is what they themselves create or pass in, there is no contention.
cletus
+4  A: 

Making your code thread safe can be as simple as adding a comment that says the class was not designed for concurrent use by multiple threads. So, in that sense: yes, all of your classes should be thread safe.

However, in practice, many, many types are likely to be used by only a single thread, often only referenced as local variables. This can be true even if the program as a whole is multi-threaded. It would be a mistake to make every object safe for multi-threaded access. While the penalty may be small, it is pervasive, and can add up to be a significant, hard-to-fix performance problem.

erickson
+1 for mentioning the use of comments to state design intentions
Tim Bender
I wouldn't say that "adding a comment" is the same as "Making your code thread safe." The latter implies that the class itself handles all necessary synchronization. Whether or not your code is thread safe, a comment in its Javadoc will save other programmers time and effort. :)
Cody Casterline
+2  A: 

I advise you to obtain a copy of "Effective Java", 2nd Ed. by Joshua Bloch. That book devotes a whole chapter to concurrency, including a solid exploration of the issue of when (and when not) to synchronize. Note, for example, the title of item 67 in "Effective Java": 'Avoid excessive synchronization', which is elaborated over five pages.

David
Synchronization is not necessarily needed to make thread safe.
Thorbjørn Ravn Andersen
+1  A: 

As was stated previously, you need thread safety when you think your code will be used in a multithreaded environment.

Consider the approach taken by the Collections classes, where you provide a thread-unsafe class that does all its work without using synchronize, and you also provide another class that wraps the unsynchonized class and providing all of the same public methods but making them synchronize on the underlying object.

This gives your clients a choice of using the multi-threaded or the single-threaded version of your code. It may also simplify your coding by isolating all of the threading/locking logic in a separate class.

Loadmaster