I'm having a little difficulty understanding volatile variables in Java.
I have a parameterized class that contains a volatile variable like so:
public class MyClass<T> {
private volatile T lastValue;
// ... other code ...
}
I have to implement certain basic operations against lastValue
including a get-value-if-not-null.
Do these operations need to be synchronized? Can I get away with doing the following method?
public void doSomething() {
String someString;
...
if (lastValue != null) {
someString += lastValue.toString();
}
}
Or do I need to stick the null check into a synchronized block?
public void doSomething() {
String someString;
...
synchronized(this) {
if (lastValue != null) {
someString += lastValue.toString();
}
}
}
I know that for atomic operations like get and set, I should be ok without applying synchronization (eg. public T getValue() { return lastValue; }
). But I wasn't sure about non-atomic operations.
volatile
guarantees visibility (changes made by one thread will be seen by other threads) but it does not guarantee atomicity of several operations.
So yes, lastValue
could become null
between if (lastValue != null)
and someString += lastValue.toString();
and your code could throw a NullPointerException
.
You can either add synchronization (but you will need to synchronize all write accesses to the variable), or for that simple use case, you can use a local variable:
public void doSomething() {
String someString;
T lastValueCopy = lastValue;
if (lastValueCopy != null) {
someString += lastValueCopy.toString();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With