As I red somewhere, when we have synchronized methods, only one thread can use any of those method at the same time. The problem is that I have small peace of code that looks to break this rule, and I hope some of you knows why.
import java.util.Date;
public class SyncTest extends Thread {
private int state;
public static final int STATE_STOP = 10;
public static final int STATE_DO_TASK = 2;
public static final int STATE_FREE = 0;
public void run() {
try {
while(getThisState() != STATE_STOP) {
if(getThisState() == STATE_DO_TASK) {
Thread.sleep(2000);
setState(0);
}
}
}catch(Exception ex) {
ex.printStackTrace();
}
}
public synchronized void setState(int newState) {
this.state = newState;
this.notify();
}
public synchronized int getThisState() {
return this.state;
}
public synchronized void waitForComplete(int timeoutMilisec) {
try {
while( getThisState() != STATE_FREE) {
wait(timeoutMilisec);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
SyncTest syncTest = new SyncTest();
syncTest.start();
syncTest.setState(STATE_DO_TASK);
System.out.println("Start operation: " + new Date());
syncTest.waitForComplete(30000);
syncTest.setState(STATE_STOP);
System.out.println("End operation: " + new Date());
}
}
What we have here is 'waitForComplete' method, that waits until state equals zero. While main thread waits, second thread is sleeping 5 seconds and then calls setState method. This changes 'state' variable to zero, and calls notify what unlocks waiting in main process. That seems to make sense, but the question is: How the hell it is possible that second thread executes 'setState' when on the same time main thread is inside 'waitForComplete' method. Both methods are synchronized, so it should be impossible to execute them simultaneously.