Not sure whether this D class thread is correct. Is there a race condition, is i
supposed to be in a synchronized block when accessed? What if D is an outer class, and the A instance was passed to a D constructor?
class A
{
int i;
void f() {
i++;
D d = new D();
d.start();
}
class D extends Thread {
public void run() {
int g = i;
}
}
}
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:
i
again, including by invoking foo
againi
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.