No, its not safe.

Under the Java memory model, a thread can read the userHome member and see the java.io.File object's reference, but be unable to see the fields assigned within the object.  It could be seeing garbage from the prior resident of that location, or it could be seeing all NULs from the allocator clearing the region before initialization.

The only way to ensure that all writes up to a particular point are visible, and thus that the object(s) in question are internally consistent from the perspective of a reader, is to travel through a synchronization barrier.  Those barriers exist at a synchronized block, or when writing/reading a volatile.

The memory model requires that all writes carried out within a thread prior to a write to a volatile must be visible to another thread that reads that volatile first.  Or, that all writes carried out before releasing a monitor on an object must be visible to another thread after it acquires that same monitor.

Anything else is playing with fire.

So.  Either delete the userHome property and compute it on the fly every time its requested, or use a volatile.

Given that on Cygwin userHome is computed via a fork+exec, that's pretty expensive.  We could permit the default implementation to compute on demand every time, but we still should cache the result in the Cygwin case.  Which brings us right back to this discussion of needing to mark the field volatile.  :-)