I am a little confused because I know reads of doubles are not atomic, but because this class has no setters or getters is anything needed to be done in order to ensure this is thread safe?
Yes, you need to make sure that x
and y
are marked as final
. That has nothing to do with it being double
however. final
fields are guaranteed to be fully initialized when the vector
(it should be Vector
btw) is constructed. Without the final
if you shared an instance of vector
without synchronization, the compiler can reorder the field initializations past the point when the constructor finishes and the x
and y
fields may be not initialized or partially so. So another thread might see x
and y
as 0 or with only one of the words updated. For more information, see Constructor synchronization in Java
If you are taking about mutable fields (that can't be final
) then whether or not the double
will be fully updated depends on the architecture you are running on. To be safe you will have to make them volatile
to make sure that they are fully updated and published when they are changed.
As @Voo pointed out, if you are updating x
and then y
then that is 2 separate operations and your distance calculation might see only one of the two fields updated -- even if they are both volatile
. If you need that to be atomic then you should use an AtomicReference
and have a little container class that holds both x
and y
. AtomicReference
wraps a volatile Object
.
Something like:
private final AtomicReference<XAndY> xyRef = new AtomicReference<XAndY>();
...
public void setXAndY(double x, double y) {
xyRef.set(new XAndY(x, y));
}
...
public double getDist() {
// get a local instance of our object which is atomic
XAndY xAndY = xyRef.get();
return Math.sqrt(xAndY.x * xAndY.x + xAndY.y * xAndY.y);
}
...
private static class XAndY {
double x;
double y;
}