Win a copy of Programmer's Guide to Java SE 8 Oracle Certified Associate (OCA) this week in the OCAJP forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Need your help -- IllegalMonitorStateException

 
May Wong
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi everyone,
I went through all the posts about IllegalMonitorStateException, but still can not figure out what's wrong with my program. Does anyone can help me taking a look, whatever the problem is? Thank you!!

public class LockManager {
public static int DATABASE_LOCK_RECORD = -1;
public static int INVALID_RECORD_LINE = -2;
public static int NULL_RECORD = 0;
private DBLock dblock;
private RecordLock reclock;
private Map lockMap_;
private DataAccessIF conn_;
public LockManager(){
dblock = new DBLock();
reclock = new RecordLock();
lockMap_ = Collections.synchronizedMap(new HashMap());
}
class DBLock{
private boolean isLocked = false;
void LockDB() throws IOException{
isLocked = true;
while (lockMap_.size() > 0){
try{
lockMap_.wait();
}catch (InterruptedException e) {
throw new IOException("DB Lock was failed!");
}
}
}
void UnlockDB(){
if (isLocked == true){
isLocked = false;
lockMap_.notifyAll();
}
}
boolean DBLockNoticed() {return isLocked;}
}

class RecordLock{
void LockRecord(int renum) throws IOException{
Integer num = new Integer(renum);
while ((dblock.DBLockNoticed() == true) ||
(lockMap_.containsKey(num))){
try{
lockMap_.wait();
}catch (InterruptedException e) {
throw new IOException("Record Lock was failed!");
}
}
lockMap_.put(new Integer(renum), conn_);
}
void UnlockRecord(int renum){
Integer num = new Integer(renum);
if ((lockMap_.containsKey(num)) &&
(lockMap_.get(num) == conn_)){
lockMap_.remove(num);
lockMap_.notifyAll();
}
}
}
public synchronized void Lock(int renum, int RecordCount) throws IOException{
conn_ = ThreadConnectionBind.getCurrentThreadConnection();
if (renum < INVALID_RECORD_LINE ||
renum > RecordCount ||
renum == NULL_RECORD){
throw new IOException("The record position is invalid.");
}
if (renum != DATABASE_LOCK_RECORD)
reclock.LockRecord(renum);
else
dblock.LockDB();
}
public synchronized void Unlock(int renum, int RecordCount){
conn_ = ThreadConnectionBind.getCurrentThreadConnection();
if (renum < INVALID_RECORD_LINE ||
renum > RecordCount ||
renum == NULL_RECORD)
return;
if (renum != DATABASE_LOCK_RECORD)
reclock.UnlockRecord(renum);
else
dblock.UnlockDB();
}
}
May
 
Mike Birken
Greenhorn
Posts: 20
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
To notify/wait on an object, a thread must obtain the monitor first (i.e. it must synchronize on the object). Before you modify the object, you probably need it synchronized anyway.
- Mike
 
May Wong
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you Mike,
It works well now, after I moved synchronized from lock/unlock method to lockMap_ object. Just curious that I defined lockMap_ like:
lockMap_ = Collections.synchronizedMap(new HashMap());
Even though do I have to synchronized it?
And, if I choose object.wait/notifyall, then couldn't I use method synchronized, say void synchronized lock(int recnum), anymore?
-May
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic