Vishwanath Krishnamurthi's blog

A blog on Java EE, clean code, open source and TDD

Is this thread-safe ? (Part 1)

with 4 comments

To learn and understand about thread-safety or concurrency in general, there can’t be a better book than “Java Concurrency in Practice

Even if you cannot find the time to read through the book, the booksite contains a lot of code snippets on thread-safe / non-thread-safe code, which I’d highly recommend going through.

In this blog post, I have added a few classes, some of them are thread-safe and some of them are not.  Take it up as a quick quiz or an exercise to identify which are thread-safe and which are not and see how well you fair 🙂

public class One {

public void aMethod() {
int a = 100;
a++;
System.out.println(a);
}
}

There’s no “mutable-shared-state” in the above class. So yeah, it is thread-safe.

class Two {

private int a = 100;

public void aMethod() {
a++;
System.out.println(a);
}

}

In class Two, ‘a’ is a mutable shared state and the operation being done (a++) is not atomic. This could lead to race-conditions
and hence class Two is not thread-safe

class Three {

private boolean toggleSwitch = true;

public void aMethod() {
toggleSwitch = !toggleSwitch;
System.out.println(toggleSwitch);
}

}

When two threads are changing the state (toggleSwitch) you cannot guarantee that the change done by threadA is visible for the
other thread.  So we have got ‘thread-visibility’ problems in the above class.

class Four {

private volatile boolean toggleSwitch = true;

public void aMethod() {
toggleSwitch = !toggleSwitch;
System.out.println(toggleSwitch);
}

}

We’ve addressed the problem we had at ‘class Three’ by making ‘toggleSwitch’ volatile. So we are good for class Four. Class Four is thread-safe.  Update: Oops, wait ! Class Four is not thread safe.  As Pravin has pointed out in the comments-

class Five {

private volatile int a = 100;

public void aMethod() {
a++;
System.out.println(a);
}

}

This code looks pretty much like class Four. So is this thread-safe too ? Nope.
Visibility and atomicity are two separate things. Here a++ is not an atomic operation and you could have a race condition. So class Five is not thread safe.

class Six {

private AtomicInteger a = new AtomicInteger(100);

public void aMethod() {
a.incrementAndGet();
System.out.println(a);
}

}

We’ve addressed the atomicity problem. Atomic* operations are also documented to behave like ‘volatile’. So visibility is covered too
so class Six here is thread-safe.

class Seven {

int a = 100;

public synchronized void aMethod() {
a++;
System.out.println(a);
}

}

Note that ‘a’ is not private. Nothing prevents a thread from directly accessing the field and modifying the state. So class Seven is not thread-safe

class Eight{

private int a = 100;

public synchronized void aMethod() {
a++;
System.out.println(a);
}

}

Well, only aMethod() could change the state of ‘a’ now. And it is synchronized.
So yeah, class Eight is thread-safe. But we did not make ‘a’ volatile !
Well, there’s no need to.  ‘Synchronizing’ addresses both ‘atomicity’ and ‘thread visibility’ problems so we are good here.

Resources:

Apart from the book, do check out the “concurrency animations” !

Written by Vishwanath Krishnamurthi

October 1, 2013 at 9:55 am

4 Responses

Subscribe to comments with RSS.

  1. In class 4, don’t you think that “toggleSwitch = !toggleSwitch;” is not atomic?

    Pravin

    June 13, 2014 at 3:45 pm

    • Yes, you’re right. That is not atomic and hence not thread-safe. Thanks for pointing it out ! For mere ‘read’s or ‘write’s a volatile boolean would have sufficed but for a ‘read-modify-write’ operation, as it was in this case, there’s atomicity to consider as well.

      • Good post, Vishwanath. JCP is a must read for any serious java developer.

        Shridhar

        August 9, 2016 at 2:02 am

  2. […] at this blog, Vishwanath tells us something interesting. Never stake entirely on such a code to give you […]


Leave a comment