You know what thread safety is, right? If not, there is a simple example below. All classes must be thread-safe, right? Not really. Some of them have to be thread-safe? Wrong again. I think none of them have to be thread-safe, while all of them have to provide synchronized decorators.
Let's start with an example (it's mutable, by the way):
What do you think — is it thread-safe? This term refers to whether an object of this class will operate without mistakes when used by multiple threads at the same time. Let's say we have two threads working with the same object,
position, and calling its method
increment() at exactly the same moment in time.
We expect the
number integer to be equal to 2 when both threads finish up, because each of them will increment it once, right? However, most likely this won't happen.
Let's see what will happen. In both threads,
before will equal
0 when they start. Then
after will be set to
1. Then, both threads will do
this.number = 1 and we will end up with
number instead of the expected
2. See the problem? Classes with such a flaw in their design are not thread-safe.
The simplest and most obvious solution is to make our method
synchronized. That will guarantee that no matter how many threads call it at the same time, they will all go sequentially, not in parallel: one thread after another. Of course, it will take longer, but it will prevent that mistake from happening:
A class that guarantees it won't break no matter how many threads are working with it is called thread-safe.
Now the question is: Do we have to make all classes thread-safe or only some of them? It would seem to be better to have all classes error-free, right? Why would anyone want an object that may break at some point? Well, not exactly. Remember, there is a performance concern involved; we don't often have multiple threads, and we always want our objects to run as fast as possible. A between-threads synchronization mechanism will definitely slow us down.
I think the right approach is to have two classes. The first one is not thread-safe, while the other one is a synchronized decorator, which would look like this:
Now, when we need our
position object to be thread-safe, we decorate it with
When we need a plain simple position, without any thread safety, we do this:
Making class functionality both rich and thread-safe is, in my opinion, a violation of that famous single responsibility principle.
By the way, this problem is very close to the one of defensive programming and validators.