This is safe as long as you only invoke f
once. There is a happens-before relationship between a thread A that mutates data and a thread B that's started from thread A (the HB-relationship being at Thread.start
). Since nobody mutates data after D
is started, this is safe.
Some ways to break the thread safety:
- mutate
i
again, including by invoking foo
again
- read
i
from a thread other than D
or the one that invoked foo
The reason that you can't mutate i
again, even from the thread that invoked foo
, is that this mutation would have happened after d.start()
, and would therefore have no HB edge against that second mutation.
The reason you can't read i
from any arbitrary thread is that this thread wouldn't have a well-defined view of the i++
mutation.
It can get a tad more subtle than that, but at a high level, there you go.