1

Class A's methods are accessed by two threads. One thread updates it. The other retrieves its member.

public class A {
    private V v;

    public V getV() {
        return v;
    }

    public V updateV(A a, B b, Cc) {
        //complex logic updating V
    }
}

How can I make V thread safe?

Nicolas Filotto
  • 43,537
  • 11
  • 94
  • 122
Sandah Aung
  • 6,156
  • 15
  • 56
  • 98
  • Please provide the code of the class V – Nicolas Filotto Aug 03 '16 at 08:06
  • 1
    Is really **updating** the existing instance of V or is it creating a new instance replacing the old one? – Fildor Aug 03 '16 at 08:09
  • 1
    Can you return a defensive copy of `v` from the getter, or do the updates have to be visible in all previously-returned instances? – Andy Turner Aug 03 '16 at 08:10
  • You are asking for a tutorial on thread safety. Entire books have been written that give the answer to your question. – Raedwald Aug 03 '16 at 08:43
  • @Raedwald No. I am not asking for a tutorial. I just wanted to get some information about my specific case. Looks as if some people in my company had to sift through some lengthy tutorials on thread safety before arriving at some vague conclusions so I thought it would be a great idea to make it a question. – Sandah Aung Aug 03 '16 at 11:28

1 Answers1

2

The easiest way to make V thread safe is to make it immutable (by making final all its non static fields) then in A you simply affect a new instance of V in updateV as next:

public class A {
    private V v;

    public synchronized V getV() {
        return v;
    }

    public synchronized V updateV(A a, B b, Cc) {
        //complex logic updating V
        this.v = new V(...);
        return v;
    }
}

As you can see to make A thread safe I simply added the keyword synchronized to the getter and the setter to prevent concurrent read and write but if it is not needed in your case you can sill make v volatile as next:

public class A {
    private volatile V v;

    public V getV() {
        return v;
    }

    public V updateV(A a, B b, Cc) {
        //complex logic updating V
        this.v = new V(...);
        return v;
    }
}
Nicolas Filotto
  • 43,537
  • 11
  • 94
  • 122
  • If you only use the synchronised version you have no garante that the field is not anymore in a cache. You should use volatile in this case to ensure the visibility. – Nicolas Henneaux Aug 03 '16 at 08:45
  • @NicolasHenneaux I don't think so, you use synchronized or volatile not both check for example the code of the class Vector (or any thread safe class based on synchronized) you will see that all fields representing the state are not volatile – Nicolas Filotto Aug 03 '16 at 09:01
  • 1
    Your are right synchronized keyword on a same object (the instance in this case) cause a memory barrier (see https://stackoverflow.com/questions/3519664/difference-between-volatile-and-synchronized-in-java). – Nicolas Henneaux Aug 03 '16 at 09:06