· 3 min read

Making Object Immutable for Concurrency

It's best to start with immutable objects and then modify them if needed.

It's best to start with immutable objects and then modify them if needed.

Photo by Dave Hoefler on Unsplash

{% include note.html content=“For beginners: Immutable object means objects whose value can’t change. Immutability is the intent of the creator of the object/class, i.e. when coding something up, we need to decide if a particular class should be immutable. Also, immutability is as important in the front end as in the back end. While the below posts explain it in Java, other programming languages have their way of implementing immutability.” %}

Where Immutability is needed?

When sharing data between threads, there is a high chance that one memory gets replaced by another. This would lead to inconsistency, and often these bugs aren’t discovered.

There are two ways to avoid this: thread-safe data structures or immutable objects.

This particular post will explain where immutable objects are necessary.

Suppose you have 2 Rest Endpoints. /someEndpoint and /anotherEndpoint both set a particular value to the variable sharedMemory.

private String sharedMemory;

@PostMapping("/someEndpoint")
void postSomething(@RequestBody String value){
    sharedMemory = value;
    ....
   //some code that uses sharedMemory
}

@PostMapping("/anotherEndpoint")
void postSomethingElse(@RequestBody String value){
    sharedMemory = value;
    ....
   //some code that uses sharedMemory
}

It can happen that this shared memory is not inconsistent.

Ideally, the solution would be, in this case, to declare the variable within the method it is used.

Creating an immutable object

The creation of immutable objects is relatively simple.

  1. Make sure all instance variables are private final.
  2. make sure all interactions with the method happens only via the constructor or the public method. No method should modify the contents of the private final method.
  3. Make sure all instance variables are immutable.
  4. Make sure the class is final so that there is no inheriting and subclasses can’t override something.

There are some more rules, but these are the minimum requirements. The following section will explain how you automate the checking of immutable classes would also check for more conditions.

Java Libraries

Some libraries help create immutable objects, such as Immutables for Java.

Google Guava Library provides many immutable data structure alternatives. The benefit of using these is that they have the same interface as regular java collections.

{% include note.html content=“It’s best to start with immutable objects and then modify them if needed.” %}

Automating Verification via Unit Tests

But when developing within a team and given the cognitive overload we developers face, we need some way to automate the creation of immutable objects. This can be done as a combo of 2 methods:

#1 Mutability Detector

Mutability Detector is a package that provides the following assertion that can be used within unit tests.

Mutability Detector has many more conditions to detect mutability.

    assertImmutable(MyClass.class); 

Github Source

#2 Automate further with ArchUnit tests

ArchUnit tests allow for writing architecture-level tests. We can write a test such as asserting that a class is immutable if a class is annotated with @component.

In practice, I couldn’t fully make assertImmutable work with abstract classes.

Resources

Back to Blog