java volatile happens before guarantee