Win a copy of The Little Book of Impediments (e-book only) this week in the Agile and Other Processes forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Synchronization-lock-unlock

 
Ajit Kumar
Ranch Hand
Posts: 81
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hi Guys,
I am implementing lock & unlock
methods. I am keeping all locked records in
a vector. In lock i am synchronizing on
this vector. I am checking if a given record
is already locked. If it is locked. the
method waits.
wait();
In the unlock method, i am simply removing
the record number from the list of locked
records vector. and notifying using
notifyAll();
These two methods are implemented in Data.java
When i am executing
dataObject.lock(1);
dataObject.modify(...);
dataObject.unlock(1);
i am getting "IllegalMonitorStateException".
Did you guys come across anything like this.
Any suggestions on how to correct this error
will be appreciate.
thanks
 
Dave Boden
Ranch Hand
Posts: 37
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
IllegalMonitorStateException
Thrown to indicate that a thread has attempted to wait on an object's monitor or to notify other threads waiting on an object's monitor without owning the specified monitor.
OK, so you're synchronising on your Vector. I'm betting that the problem comes up because you're just trying to call myVector.notifyAll(); You can't do this unless you are synchronized on the vector at the time:
e.g.
<pre>
//The synchronize in the method signature synchronizes on "this"
public void synchronized unlock() {
//This synchronized block is important!
synchronized(myVector) {
//blah
//blah
//blah
myVector.remove(mylock);
myVector.notifyAll();
}
}
</pre>
[This message has been edited by Dave Boden (edited March 05, 2001).]
 
Ajit Kumar
Ranch Hand
Posts: 81
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,
Initially, i had an idea of having a synchronized method making calls to lock, modify and unlock. But that will not allow concurrent access to multiple clients.
May be we are doing the same here also by making the lock method Synchronized? My idea is to let any client get to the lock method but wait inside this method. (or) Are these two approaches same?.
What do you think.
Thanks
 
Dave Boden
Ranch Hand
Posts: 37
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
As long as you're synchronized on some object, and you are consistant with that decision, you are fine when it comes to multithreading.
Think about what you're synchronizing on when you declare a method synchronized... "this"
If you're synchronizing on the Vector, you don't need to declare the lock() or unlock() methods as synchronized.
When you declare:
<pre>
public synchronized void myMethod() {
//BODY
}
</pre>
You are really doing this:
<pre>
public void myMethod() {
synchronized(this) {
//BODY
}
}
</pre>
 
Debajyoti Pathak
Ranch Hand
Posts: 39
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ajit,
I guess you are just calling wait() or notifyAll(). You should call wait() or notifyAll() on the vector.
i.e vector.wait(); etc
Deb
Originally posted by Ajit Kumar:
hi Guys,
I am implementing lock & unlock
methods. I am keeping all locked records in
a vector. In lock i am synchronizing on
this vector. I am checking if a given record
is already locked. If it is locked. the
method waits.
wait();
In the unlock method, i am simply removing
the record number from the list of locked
records vector. and notifying using
notifyAll();
These two methods are implemented in Data.java
When i am executing
dataObject.lock(1);
dataObject.modify(...);
dataObject.unlock(1);
i am getting "IllegalMonitorStateException".
Did you guys come across anything like this.
Any suggestions on how to correct this error
will be appreciate.
thanks

 
Ajit Kumar
Ranch Hand
Posts: 81
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,
1. This is an example program i wrote.
here test.java has the waitMethod and notifyMethod defined and test1.java is calling them.
i am calling wait an notifyAll on the Vector object only.
Do you guys see any problem with this code?
2. Also, I would like to check with you guys about
- writing a method say Book that in turn calls lock/modify/unlock methods in sequence. Make this Book method Synchronized. Make sure that there is only one instance of the class where this Book method is implemented (Data.java or whichever). This makes sure that only one client will be able to access the book method anytime.
Is this a good approach? what do you guys feel about this.

thanks in advance.
----------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----------
 
Keith Wheeles
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You lose the monitor (synchronization) on the obj when you call wait. The code above will throw an IllegalMonitorState exception when you call notifyAll because you no longer have the Monitor. Before calling notify you need to get the monitor again (synchronize on the obj).
If you implement a book method that is synchronized across lock, write, unlock - you no longer need to worry about the lower level synchronization in your test prototype. I would not personally do the book method synchronized across all of those because of the assignment requirement that all public methods of Data be shown by the client. The synchronized book method within Data would be fine, but now if the client relies on the lock, modify, and unlock methods (which are public) they don't have the right functionality separate from the book method.
Keith
 
Ajit Kumar
Ranch Hand
Posts: 81
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hi Keith,
-I put the code to synchronize on the obj
public void notifyMethod(int record) {
synchronized(objToSync){
...
and it is working now. Thanks.
- I agree with your comments on the book method.
I have a question here.
As youcan see, i have a 'conditional statement if (i==10) for calling wait() on the object'. This statement will never get executed as the variable i is set to 1 at the beginning of the method.
When i removed that condition and allow the wait statement to get executed, the program is pringing "waiting" correctly, but it is not getting into the body of notifyMethod (notify now has the sync statement on the Vector object).
I am assuming that the current thread is holding a lock on the Vector object as it is waiting from the middle of the sync code block(of waitMethod). And again the code looks for a lock on the same Vector object in the notifyMethod method. And since this lock is never got it is entering into a 'deadlock' situation.
Is my understanding correct? Please offer your comments.
thanks for your suggestions
 
Keith Wheeles
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ajit -
The thread goes into a wait properly, so it can't run the notify method to wake itself up. The notifyAll would need to be in another thread in order to wake this one up.
Keith
 
Ajit Kumar
Ranch Hand
Posts: 81
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Got it. Thanks.
We know that RMI does not guarantee that different clients will be handled through different threads.
Can i still assume that if more than one client is connected to this object (If i make it an RMI server with these two methods), this does not lead to a deadlock. I am assuming because there will be more number of threads than one and if one is in the wait state, the other thread will notify it once it is done with the processing?
Thanks
 
Max Tomlinson
Ranch Hand
Posts: 365
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
synchronized revisted...
Like many of you, I am using a HashMap to hold my record locks.
private Map lockTable = Collections.synchronizedMap(new HashMap());
My question is: can I simply lock the table by making the 'lock' and 'unlock' methods of the Data class 'synchronized'? Seems to me that is the cleanest solution provided it is not too restrictive.
thanks in advance,
Max
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic