John T.
John T.

Reputation: 193

java - volatile keyword also for non-primitives

I am unsure if the volatile keyword should also be used for non-primitives. I have a class member which is set/assigned by one thread, and accessed by another thread. Should I declare this member volatile?

private /* volatile */ Object o;

public void setMember(Object o) {
    this.o = o;
}

public Object getMember() {
    return o;
}

Here, setMember(...) is called by one thread and getMember() is called by another one.

If it was a boolean, for example, the answer would be yes.

I am using Java 1.4 and the member in this case is read-only. So I am only caring about visibility in this case, hence my question about the volatile keyword.

Upvotes: 17

Views: 5412

Answers (4)

Kanagavelu Sugumar
Kanagavelu Sugumar

Reputation: 19260

If we look up AtomicInteger class, it has declared value as volatile , So it can be used in multi-threaded environment without any thread cache issue.

public class AtomicInteger {
    private volatile int value;

    /**
     * Gets the current value.
     *
     * @return the current value
     */
    public final int get() {
        return value;
    }

    /**
     * Sets to the given value.
     *
     * @param newValue the new value
     */
    public final void set(int newValue) {
        value = newValue;
    }

}

But if you think reference to AtomicInteger it shelf will be modified with different AtomicInteger objects by many threads; then you need volatile for that reference too.

private volatile AtomicInteger reference = new AtomicInteger(0);

Mostly it won't be the case; only value of the object will changed; hence declare it as final.

private final AtomicInteger reference = new AtomicInteger(0);

Upvotes: 1

Tomasz Nurkiewicz
Tomasz Nurkiewicz

Reputation: 340693

Yes, your code is correct. In this case the reference itself is volatile, so chances to the reference are automatically visible in all other threads, but not changes to the object being referenced.

Upvotes: 4

Michael Borgwardt
Michael Borgwardt

Reputation: 346260

Yes - volatile has exactly the same significance for reference-type fields that it has for primitive-type fields. Except that in the case of reference types, the members of the object the field refers to must also be designed for multi-threaded access.

Upvotes: 12

Affe
Affe

Reputation: 47954

You can, and it may be helpful, but remember the keyword just applies to the setting of the reference. It has no effect on multi-thread visibility of the properties inside that object. If it is stateful, you probably want to synchronize around each access to it anyway, to ensure the desired happens-before relationships.

Upvotes: 8

Related Questions