Thread Safety in Java Using Atomic Variables

Mis94 :

I have a Java class, here's its code:

public class MyClass {
    private AtomicInteger currentIndex;
    private List<String> list;

    MyClass(List<String> list) {
        this.list = list; // list is initialized only one time in this constructor and is not modified anywhere in the class
        this.currentIndex = new AtomicInteger(0);
    }

    public String select() {
        return list.get(currentIndex.getAndIncrement() % list.size());
    }
}

Now my question:

Is this class really thread safe thanks to using an AtomicInteger only or there must be an addional thread safety mechansim to ensure thread-safety (for example locks)?

Erwin Bolwidt :

The use of currentIndex.getAndIncrement() is perfectly thread-safe. However, you need a change to your code to make it thread-safe in all circumstances.

The fields currentIndex and list need to be made final to achieve full thread-safety, even on unsafe publication of the reference to your MyClass object.

private final AtomicInteger currentIndex;
private final List<String> list;

In practice, if you always ensure that your MyClass object itself is safely published, for example if you create it on the main thread, before any of the threads that use it are started, then you don't need the fields to be final.

Safe publication means that the reference to the MyClass object itself is done in a way that has a guaranteed multi-threaded ordering in the Java Memory Model.

It could be that:

  • All threads that use the reference get it from a field that was initialized by the thread that started them, before their thread was started
  • All threads that use the reference get it from a method that was synchronized on the same object as the code that set the reference (you have a synchronized getter and setter for the field)
  • You make the field that contains the reference volatile
  • It was in a final field if that final field was initialized as described in section 17.5 of the JLS.
  • A few more cases the are not easily used to publish references

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=114631&siteId=1