The first
thread enters the synchronized "run" method. The state field is 0 after the initialization, so the thread enters the if block and prints its id. The second thread cannot yet enter the run method, as the method is synchronized on the w1 object, which is already locked by the first thread.
But then the first thread frees the lock by calling the wait method on the w1 object (which is referred with a "this" link), and the second thread enters the run method and also prints its id. Then the second thread also frees the lock calling the wait method.
But as the wait methods are run without parameters, this means that both threads will wait until some other thread calls notify on the w1 object, which will never happen, because the third and second thread run on another object, w2, independently, and stuck in the same situation (state field is not static, so it's also 0 at the initialization of the w2 object), managing only to print their ids just once. So we have 4 different ids printed on the screen, which corresponds to the D answer.