Home » Java » Core Java » Synchronized Decorators to Replace Thread-Safe Classes

About Yegor Bugayenko

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.

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;

(0 rating, 0 votes)
You need to be a registered member to rate this.
3 Comments Views Tweet it!
Do you want to know how to develop your skillset to become a Java Rockstar?
Subscribe to our newsletter to start Rocking right now!
To get you started we give you our best selling eBooks for FREE!
1. JPA Mini Book
2. JVM Troubleshooting Guide
3. JUnit Tutorial for Unit Testing
4. Java Annotations Tutorial
5. Java Interview Questions
6. Spring Interview Questions
7. Android UI Design
and many more ....
I agree to the Terms and Privacy Policy

3
Leave a Reply

avatar
3 Comment threads
0 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
3 Comment authors
nathanVishal_AmleIgnacio Arces Recent comment authors

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

  Subscribe  
newest oldest most voted
Notify of
Ignacio Arces
Guest
Ignacio Arces

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
Guest
Vishal_Amle

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

nathan
Guest
nathan

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.