I am trying to wrap my head around thread safety in java (or in general). I have this class (which I hope complies with the definition of a POJO) which also needs to be compatible with JPA providers:
public class SomeClass {
private Object timestampLock = new Object();
// are "volatile"s necessary?
private volatile java.sql.Timestamp timestamp;
private volatile String timestampTimeZoneName;
private volatile BigDecimal someValue;
public ZonedDateTime getTimestamp() {
// is synchronisation necessary here? is this the correct usage?
synchronized (timestampLock) {
return ZonedDateTime.ofInstant(timestamp.toInstant(), ZoneId.of(timestampTimeZoneName));
}
}
public void setTimestamp(ZonedDateTime dateTime) {
// is this the correct usage?
synchronized (timestampLock) {
this.timestamp = java.sql.Timestamp.from(dateTime.toInstant());
this.timestampTimeZoneName = dateTime.getZone().getId();
}
}
// is synchronisation required?
public BigDecimal getSomeValue() {
return someValue;
}
// is synchronisation required?
public void setSomeValue(BigDecimal val) {
someValue = val;
}
}
As stated in the commented rows in the code, is it necessary to define timestamp
and timestampTimeZoneName
as volatile
and are the synchronized
blocks used as they should be? Or should I use only the synchronized
blocks and not define timestamp
and timestampTimeZoneName
as volatile
? A timestampTimeZoneName
of a timestamp
should not be erroneously matched with another timestamp
's.
This link says
Reads and writes are atomic for all variables declared volatile (including long and double variables)
Should I understand that accesses to someValue
in this code through the setter/getter are thread safe thanks to volatile
definitions? If so, is there a better (I do not know what "better" might mean here) way to accomplish this?