That's the tearing problem.
It gets worse because things you can't generally do in the JVM can happen. For example, if your value class contains a reference to an object but that reference just so happens to split a tear, it's possible one thread to see an invalid reference while another thread is writing that object. That could be fixed with some added padding based on the architecture to make sure stored references aren't tearable.
But tearing may still cause a logical issue of course. (Think of a date class where the day may still be 31 but the month was set to Feb on another thread).
Interestingly Go is memory unsafe on this issue, slices can tear and later code can read into an incorrect offset from the pointer. Java abstracts away pointers, so this issue is non-existant there.
You can assign the object again to overwrite it 'in place'.
> And a simple write-lock bit for fat Value Types would solve everything while maintaining most of the performance benefits (both on read and write)
They even already have an extra 'null' bit tacked on to the value object.