Search code examples
javamultithreadingjava.util.concurrent

Java synchronized thread


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;
        }
    }
}

Solution

  • 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.