-
synchronization question
Hi everyone,
i'm new to forums and java threads.
As i was studying threads, i encountered the two sample classes below:
Code:
class NewThread implements Runnable {
String name; // name of thread
Thread t;
boolean suspendFlag;
NewThread(String threadname) {
name = threadname;
t = new Thread(this, name);
System.out.println("New thread: " + t);
suspendFlag = false;
t.start(); // Start the thread
}
// This is the entry point for thread.
public void run() {
try {
for (int i = 15; i > 0; i--) {
System.out.println(name + ": " + i);
Thread.sleep(200);
synchronized (this) {
while (suspendFlag) {
wait();
}
}
}
} catch (InterruptedException e) {
System.out.println(name + " interrupted.");
}
System.out.println(name + " exiting.");
}
void mysuspend() {
suspendFlag = true;
}
synchronized void myresume() {
suspendFlag = false;
notify();
}
}
Code:
class SuspendResume {
public static void main(String args[]) {
NewThread ob1 = new NewThread("One");
NewThread ob2 = new NewThread("Two");
try {
Thread.sleep(1000);
ob1.mysuspend();
System.out.println("Suspending thread One");
Thread.sleep(1000);
ob1.myresume();
System.out.println("Resuming thread One");
ob2.mysuspend();
System.out.println("Suspending thread Two");
Thread.sleep(1000);
ob2.myresume();
System.out.println("Resuming thread Two");
} catch (InterruptedException e) {
System.out.println("Main thread Interrupted");
}
// wait for threads to finish
try {
System.out.println("Waiting for threads to finish.");
ob1.t.join();
ob2.t.join();
} catch (InterruptedException e) {
System.out.println("Main thread Interrupted");
}
System.out.println("Main thread exiting.");
}
}
and there are some points i don't understant.
First why are we using synchronized as we are calling wait(). I don't see any way there could be parallel usege.
Second, when i remove the synchronized keyword from the code i get java.lang.IllegalMonitorStateException. After this if i also remove the lines with ob2 i don't get any exception. How come removing ob2 affects ob1 and prevents the program from throwing exception ?
As i said before, i'm new to threads, and if you could help me i would really appriciate it.
-
After this if i also remove the lines with ob2 i don't get any exception. How come removing ob2 affects ob1 and prevents the program from throwing exception ?
I tried this (removing ob2) and I still got the same exceptions in the console:
Code:
Exception in thread "One" java.lang.IllegalMonitorStateException: current thread
not owner
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Unknown Source)
at NewThread.run(suspendresume.java:59)
at java.lang.Thread.run(Unknown Source)
The key seems to be "current thread not owner".
In the Method Summary section of the Thread class api, scroll down to the section "Methods inherited from class java.lang.Object" and find the notify and wait methods.
Look these up in the Object class api and read the information in the Method Detail for each. It specifies the conditions required for a thread to obtain a lock on, and thus be the owner of, an objects monitor.
You can test this in the NewThread class with the addition of a print statement in the run method:
Code:
synchronized (this) {
Thread thread = Thread.currentThread();
System.out.printf("name = %s holdsLock = %b%n",
thread.getName(),
Thread.holdsLock(this));
while (suspendFlag) {
wait();
}
}
and see what happens in the console when you run the app with and without commenting out the two lines for the "synchronized(this)" block.
-
wait(),notify(),notifyAll() should always call from synchronized method or synchronized statement blocks.
Because when a wait() calls on a object the wait() releases the lock acquired by the synchronized method or block. If we do not place wait() inside synchronized method or block then it can't release lock on the object,so it will throw Exception