Win a copy of Think Java: How to Think Like a Computer Scientist this week in the Java in General forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

IllegalMonitorStateException

 
Ajit Kumar
Ranch Hand
Posts: 81
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hi guys,
When i am executing the following code, i am getting IllegalMonitorStateException error. What am i doing wrong here. My requirement is to make one method wait and notify through the other method.
In my program, i am calling both these methods one after the other, eventually, i would like to be able to call these two methods from another class.
Pls. let me know what am i doing wrong here.
thanks in advance.
import java.util.*;
import java.io.*;
public class test{
Vector objToSync=new Vector();
public static void main(String[] args) throws Exception{
test t=new test();
t.waitMethod(1); t.notifyMethod(2);
}
public void waitMethod(int i) throws IOException {
synchronized(objToSync){
try{
System.out.println("waiting");
wait();
}
catch(Exception e){
throw new IOException(" Error occurred " + e.toString());
}
System.out.println(i);
}// Synchronized.

}
public void notifyMethod(int record) {
synchronized(objToSync){
try{
System.out.println("Before Notify");
notifyAll();
}catch (Exception e){
System.out.println ("Exception Occurred" + e.toString());
}
} //Sync
}
}
 
Andy Ceponis
Ranch Hand
Posts: 782
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well im just a newb at java, so im probably not gonna be of much help.
Your exception means that you issued a wait and/or notifyall on an object without getting a lock for it.
Now i havent dealt with vectors yet, so im not sure how they play into this code. So i can only hazard a guess: Your notifyMethod and waitMethod are not synchronized. But since i dont know what role the synchornized vector object plays in this, i cant help ya on this part. Sorry. Hopefully at least the first part helped(probably not even that ).
 
Jim Baiter
Ranch Hand
Posts: 532
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Try synchronizing on "this" instead of the member variable. Then you'll have the lock on the current thread.
 
Peter den Haan
author
Ranch Hand
Posts: 3252
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Jim Baiter:
Try synchronizing on "this" instead of the member variable. Then you'll have the lock on the current thread.

?The thread? You mean "the current object"?
The problem is that Ajit is synchronizing on objToSync, but calling wait() and notifyAll() on the Test instance (indeed, "this"). The IllegalMonitorState exception is thrown because you don't have a monitor lock on "this".
Change "wait()" into "objToSync.wait()" and "notifyAll()" into "objToSync.notifyAll()" and you should be fine.
- Peter
 
Ajit Kumar
Ranch Hand
Posts: 81
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hi,
I tried that. May be i am missing something. Here are my two java files. The first file is test.java. It has two methods waitMethod and notifyMethod. I have another java file test1.java it makes calls to these two methods.
I would greatly appreciate you could offer your comments.
------------test.java-------------------------
import java.util.*;
import java.io.*;
public class test{
Vector objToSync=new Vector();
public static void main(String[] args) throws Exception{
test t=new test();
t.waitMethod(1); t.notifyMethod(2);
}
public void waitMethod(int i) throws IOException {
i=1;
synchronized(objToSync){
try{
System.out.println("waiting");
if (i==10){// this will not happen
objToSync.wait();
}
}
catch(Exception e){
throw new IOException(" Error occurred " + e.toString());
}
System.out.println(i);
}// Synchronized.
}
public void notifyMethod(int record) {
try{
System.out.println("Before Notify");
objToSync.notifyAll();
}catch (Exception e){
System.out.println ("Exception Occurred" + e.toString());
}
}
}
----------end of test.java----------
-----test1.java-----------------------
import java.util.*;
import java.io.*;
public class test1{
public static void main(String[] args) throws Exception{
test t=new test();
t.waitMethod(1); t.notifyMethod(2);
}
}
----------end of test1.java----------
 
Ajit Kumar
Ranch Hand
Posts: 81
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,
here are my two java files. One has waitMethod and notifyMethod and the other file has calls to these two methods.
Your comments are greatly appreciated.
----------test.java----------
import java.util.*;
import java.io.*;
public class test{
Vector objToSync=new Vector();
public static void main(String[] args) throws Exception{
test t=new test();
t.waitMethod(1); t.notifyMethod(2);
}
public void waitMethod(int i) throws IOException {
i=1;
synchronized(objToSync){
try{
System.out.println("waiting");
if (i==10){// this will not happen
objToSync.wait();
}
}
catch(Exception e){
throw new IOException(" Error occurred " + e.toString());
}
System.out.println(i);
}// Synchronized.
}
public void notifyMethod(int record) {
try{
System.out.println("Before Notify");
objToSync.notifyAll();
}catch (Exception e){
System.out.println ("Exception Occurred" + e.toString());
}
}
}
----------end of test.java----------
----------test1.java----------
import java.util.*;
import java.io.*;
public class test1{
public static void main(String[] args) throws Exception{
test t=new test();
t.waitMethod(1); t.notifyMethod(2);
}
}
----------end of test1.java----------
 
Jim Baiter
Ranch Hand
Posts: 532
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, you're right - thread should be replaced with object in that sentence. Yet if I change his code to synchronized(this)
instead of his vector, it works.
[This message has been edited by Jim Baiter (edited March 05, 2001).]
 
Peter den Haan
author
Ranch Hand
Posts: 3252
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You're still calling objToSync.notifyAll() without having a monitor lock on objToSync (in other words, outside a synchronized block).
You may want to carefully read the javadoc of the java.lang.Object wait and notify methods.
HTH
- Peter
 
anmol
Greenhorn
Posts: 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

You are trying to wait on monitor without owning the monitor
try making waitmethod and notify method synchronized
that should fix it.

anmol khanna
 
Marcela Blei
Ranch Hand
Posts: 477
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
"anmol",
your name is not valid as per the Javaranch name conventions. Please refer to the document located: http://www.javaranch.com/name.jsp
 
Poornima Ganesh
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I need to get more clarity in wait() and notify() methods.
Here is a code: ClientHandler.java
Iam starting new thread ClientThread inside this ClientHandler thread. I want ClientHandler thread to wait till ClientThread returns back . Right now its starting ClientThread first time, doesnt wait and starts again another thread. How to use wait() in ClientHandler and make a notify() so that ClientHandler thread resumes and iterates in the loop again.How should I become a monitor and get synchronised lock to do all these. Immediate replies are appreciated.
class ClientHandler extends Thread {


/** Overwrite the method from java.lang.Thread */
public void run() {
System.out.println( "ClientHandler.run()");
try{
for(; {
String clientRequest = "Book";
// Now starts the thread ClientThread
new ClientThread(clientRequest).start();

}
}
catch (Exception e){
System.out.println("Caught exception in ClientHandler");
}
}
 
Poornima Ganesh
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I need to get more clarity in wait() and notify() methods.
Here is a code: ClientHandler.java
Iam starting new thread ClientThread inside this ClientHandler thread. I want ClientHandler thread to wait till ClientThread returns back . Right now its starting ClientThread first time, doesnt wait and starts again another thread. How to use wait() in ClientHandler and make a notify() so that ClientHandler thread resumes and iterates in the loop again.How should I become a monitor and get synchronised lock to do all these. Immediate replies are appreciated.
class ClientHandler extends Thread {


/** Overwrite the method from java.lang.Thread */
public void run() {
System.out.println( "ClientHandler.run()");
try{
for(; {
String clientRequest = "Book";
// Now starts the thread ClientThread
new ClientThread(clientRequest).start();

}
}
catch (Exception e){
System.out.println("Caught exception in ClientHandler");
}
}
}
 
Poornima Ganesh
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Its Poornima again.Iam not sure why this smilies appear .
the code is for(; ;){
[This message has been edited by Marilyn deQueiroz (edited September 12, 2001).]
 
Girish Pednekar
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
First of all the smilies appear because your code is not enclosed in [C O D E ] [/ C O D E ] blocks (without the spaces). Actually just found out they appear even within these blocks. just add a space between ; and ) to avoid them
To answer ur question off the top of my head, here's how I would write the code (not tested it so don't blame me) someone correct me if I'm wrong

In the ClientThread class at the appropriate place put the following code

(this) keyword, as u might know, is just for clarity, not a requirement.
thanks,
GP
[This message has been edited by Girish Pednekar (edited August 23, 2001).]
[This message has been edited by Girish Pednekar (edited August 23, 2001).]
 
Poornima Ganesh
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Girish for the response. My question was how to make the first thread (ClientHandler) wait till, ClientThread finishes execution and returns back. But u have shown me how to make ClientThread wait from ClientHandler and later notify the same. I want to do it reverse. I tried yesterday and got the results.
I have put the eg. code in the wait() and notifyall() topic today
Please check it and let me know if u have any comments.
Thanks
Poornima .
 
Anonymous
Ranch Hand
Posts: 18944
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Use join.
i.e.
ClientThread ct = new ClientThread(clientRequest);
ct.start();
ct.join();
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic