Core Java

Synchronized Decorators to Replace Thread-Safe Classes

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.
 
 
 
 
 
 
 

Aladdin (1992) by Ron Clements and John Musker

Let’s start with an example (it’s mutable, by the way):

class Position {
  private int number = 0;
  @Override
  public void increment() {
    int before = this.number;
    int after = before + 1;
    this.number = after;
  }
}

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 1 in 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:

class Position {
  private int number = 0;
  @Override
  public synchronized void increment() {
    int before = this.number;
    int after = before + 1;
    this.number = after;
  }
}

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:

class SyncPosition implements Position {
  private final Position origin;
  SyncPosition(Position pos) {
    this.origin = pos;
  }
  @Override
  public synchronized void increment() {
    this.origin.increment();
  }
}

Now, when we need our position object to be thread-safe, we decorate it with SyncPosition:

Position position = new SyncPosition(
  new SimplePosition()
);

When we need a plain simple position, without any thread safety, we do this:

Position position = new SimplePosition();

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.

You may also find these related posts interesting: What Do You Do With InterruptedException?; Why InputStream Design Is Wrong; Limit Java Method Execution Time; How to Implement an Iterating Adapter; Defensive Programming via Validating Decorators;

Yegor Bugayenko

Yegor Bugayenko is an Oracle certified Java architect, CEO of Zerocracy, author of Elegant Objects book series about object-oriented programing, lead architect and founder of Cactoos, Takes, Rultor and Jcabi, and a big fan of test automation.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

3 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Ignacio Arces
Ignacio Arces
7 years ago

I agree that classes that achieve thread-safety by having synchronized methods/blocks are slower and might be breaking SRP and definitely the synchronized decorator is a simple and elegant way to work around these issues. But after reading the article, seems to me that it suggests that synchronization is the only mean to thread-safety and that’s definitely wrong. Thread-safety is more about immutability. If the classes do not hold any mutable state that may get shared when running in a concurrent environment, then the classes are thread-safe. In other words, all immutable classes are thread-safe. Synchronization is just one way to… Read more »

Vishal_Amle
Vishal_Amle
7 years ago

Synchronized methods or blocks are expensive.
More light weight approach is using re-entrant locks.

nathan
nathan
6 years ago

You could have declared the variable position as an AtomicInteger to make it thread safe. It scales better than Synchronized since it use optimistic locking technique.

Back to top button