How to write a simple thread-safe class using a volatile variable?

I want to write a simple thread-safe class that could be used to set or get an Integer value.

The easiest way is to use the synchronized keyword:

public class MyIntegerHolder {

    private Integer value;

    synchronized public Integer getValue() {
        return value;
    }

    synchronized public void setValue(Integer value) {
        this.value = value;
    }

}

I could also try using volatile:

public class MyIntegerHolder {

    private volatile Integer value;

    public Integer getValue() {
        return value;
    }

    public void setValue(Integer value) {
        this.value = value;
    }

}

Is the class with the volatile keyword thread-safe?

Consider the following sequence of events:

  1. Thread A sets the value to 5.
  2. Thread B sets the value to 7.
  3. Thread C reads the value.

It follows from the Java Language Specification that

  • "1" happens-before "3"
  • "2" happens-before "3"

but I don't see how it could follow from the specification that "1" happens-before "2" so I suspect that "1" doesn't happen-before "2".

I suspect the thread C may read 7 or 5. I think the class with the volatile keyword is not thread-safe and the following sequence is also possible:

  1. Thread A sets the value to 5.
  2. Thread B sets the value to 7.
  3. Thread C reads 7.
  4. Thread D reads 5.
  5. Thread C reads 7.
  6. Thread D reads 5.
  7. ...

Am I correct in assuming that MyIntegerHolder with volatile is not thread-safe?

Is it possible to make a thread-safe Integer holder by using AtomicInteger:

public class MyIntegerHolder {

    private AtomicInteger atomicInteger = new AtomicInteger();

    public Integer getValue() {
        return atomicInteger.get();
    }

    public void setValue(Integer value) {
        atomicInteger.set(value);
    }

}

?

Here is a fragment of the Java Concurrency In Practice book:

"Reads and writes of atomic variables have the same memory semantics as volatile variables."

What is the best (preferably non-blocking) way of writing a thread-safe MyIntegerHolder?

If you know the answer, I would like to know why you think it is correct. Does it follow from the specification? If so, how?

Answers


The keyword synchronized is saying that if Thread A and Thread B want to access the Integer, they cannot do so simultaneously. A is telling B wait until I'm done with it.

On the other hand, volatile makes threads more "friendly". They start talking to each other and working together to perform tasks. So when B tries to access, A will inform B of everything it has done until that moment. B is now aware of the changes and can continue its job from where A left of.

In Java, you have Atomic for this reason, which under the covers use the volatile keyword, so they are doing pretty much the same thing, but they save you time and effort.

The thing you are looking for is AtomicInteger, you are right about this. For the operation you are trying to perform this is the best choice.

There are two main uses of `AtomicInteger`:

 * As an atomic counter (incrementAndGet(), etc) that can be used by many threads concurrently

 * As a primitive that supports compare-and-swap instruction (compareAndSet()) to implement non-blocking algorithms. 

To answer your question on a general note

It depends on what you need. I'm not saying synchronized is wrong and volatile is good, otherwise the nice Java people would have removed synchronized a long time ago. There is no absolute answer, there are a lot of specific cases and usage scenarios.

A few of my bookmarks:

Concurrency tips

Core Java Concurrency

Java concurrency

Update

From the Java Concurrency specification available here:

Package java.util.concurrent.atomic

A small toolkit of classes that support lock-free thread-safe programming on single variables.

Instances of classes `AtomicBoolean`, `AtomicInteger`, `AtomicLong`, and `AtomicReference` each provide access and updates to a single variable of the corresponding type.
Each class also provides appropriate utility methods for that type.
For example, classes `AtomicLong` and AtomicInteger provide atomic increment methods.

The memory effects for accesses and updates of atomics generally follow the rules for volatiles:

get has the memory effects of reading a volatile variable.
set has the memory effects of writing (assigning) a volatile variable.

Also from Here

The Java programming language volatile keyword:

(In all versions of Java) There is a global ordering on the reads and writes to a volatile variable. This implies that every thread accessing a volatile field will read its current value before continuing, instead of (potentially) using a cached value. (However, there is no guarantee about the relative ordering of volatile reads and writes with regular reads and writes, meaning that it's generally not a useful threading construct.)


Need Your Help

Issues with creating a foreign key

mysql sql database phpmyadmin

I'm having issues with setting up a relation between 2 tables called Customer and Customer_Number. I have both tables set to InnoDB both have indexes, but when I go to create the foreign key, I get...

How can I programmatically check Amazon S3 permissions with boto?

python permissions amazon-s3 boto

We have a bushy tree in a bucket on Amazon S3 with a large number of files. I just discovered that while some files have two permissions entries, as seen if one clicks on a file in the AWS Management

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.