Java: How to use synchronized and volatile
Asked Answered
O

3

5

I have two threads. The first thread calls the setX method, the second one calls the getX method. Do I have to set the methods synchronized although i have only one writing thread? And can i also solve my thread problem with the second class and the volatile variable?

public class Test {
    private int x;  

    public synchronized  void setX(int x) {
        this.x = x;
    }

    public synchronized  int getX() {
        return this.x;
    }
}

public class Test2 {
    private volatile int x; 

    public void setX(int x) {
        this.x = x;
    }

    public int getX() {
        return this.x;
    }
}
Oder answered 28/1, 2013 at 19:39 Comment(0)
P
7

Rather than use synchronized or volatile here, I'd personally use AtomicInteger:

public class Test {
    private final AtomicInteger x = new AtomicInteger();  

    public void setX(int value) {
        x.set(value);
    }

    public int getX() {
        return x.get();
    }
}

(Note that I've also fixed your get / set - previously your getX was setting, and your setX was getting...)

Pragmatics answered 28/1, 2013 at 19:42 Comment(5)
But the class with volatile is also a solution?Oder
@user1720132: I believe so, but it's less clear - you need to learn about the Java memory model in detail to reason about it. Using AtomicReference, it's obvious exactly what you're trying to achieve.Pragmatics
This is implementation independent, hence preferable.Paleoasiatic
volatile and synchronized are also implementation independent. I agree an AtomicInteger is the clearest solution though.Mammy
regarding get()/set(), Test2 looks identical to AtomicInteger, which is backed by a private volatile int, too.Irresponsive
M
1

To answer your question, yes, you need some form of synchronization. Since your shared state is a single variable, and this variable is of type int, a write will be atomic (it would not be the case if the variable was a long or a double). But you still need synchronization to make sure that you have no visibility problem: thread A could write to the variable, and thread B could not see the written value, but a previous one.

The synchronization can be implemented using synchronized, volatile, or an AtomicInteger in this case. All these techniques will ensure that the write will be visible to any subsequent read of the variable.

Mammy answered 28/1, 2013 at 19:46 Comment(0)
S
0

Volatile variable only guarantees the visibility of variable and order of codes to the Threads. But it doesnot provide threads the facility of ownership on method. Synchronized keyword let the threads to have ownership on the synchronized methods.

Going by your Query:

The first thread calls the setX method, the second one calls the getX method.Do I have to set the methods synchronized although i have only one writing thread?

Depending upon what you want. If you want that Thread2 call getX only after Thread1 calls setX then yes you need to synchronize the methods but then you would have to use wait() and notify() methods also.

can i also solve my thread problem with the second class and the volatile variable?

Again , it depends upon what you want. If you wish your Thread2 to call getX method without concerning about setX method called by other Thread then you should use volatile so that Thread2 could get up to date value of x .

Supplicate answered 28/1, 2013 at 19:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.