aspose file tools*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes two questiones about synchronized block. Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "two questiones about synchronized block." Watch "two questiones about synchronized block." New topic
Author

two questiones about synchronized block.

Yuan Ye
Ranch Hand

Joined: Mar 05, 2003
Posts: 172
Hi,all.
I encountered two problems when I am trying to use a synchronized block to implement the lock() method. The code is as below, I use a static vector reservedRecords to store all record No. that have been locked.

My questions are:
a. since the verify(recNo) method may throw a RecordNotFoundException in the block, the notifyAll() method will not be called then. Would that be a problem for other threads wait for the reservedRecords object? Should I put the notifyAll() method into a finally block?
b. The InterruptedException may be thrown by the wait() method, how should I deal with the exception? In server side or client side?
Thanks. Please give me some hints.
Philippe Maquet
Bartender

Joined: Jun 02, 2003
Posts: 1872
Hi Peter,
Before replying, I have a question : why do you wrap your recNo in a String ? An Integer would suit better IMO.
a. since the verify(recNo) method may throw a RecordNotFoundException in the block, the notifyAll() method will not be called then. Would that be a problem for other threads wait for the reservedRecords object? Should I put the notifyAll() method into a finally block?

Your notifyAll() is useless anyway. (notifyAll() only needs to be called from your unlock() method).
b. The InterruptedException may be thrown by the wait() method, how should I deal with the exception? In server side or client side?

Server-side. Anyway, it's quite unlikely that exception will be thrown. If your own code somewhere doesn't call Thread.interrupt(), it will never be thrown. But what you did in caching it seems OK.
Best,
Phil.
Yuan Ye
Ranch Hand

Joined: Mar 05, 2003
Posts: 172
HI, Phil.
Thanks for your reply. I understand now why I don't need a notifyAll() in the lock() method. But I still need it in the unlock() method, right. So my question is that if there is some exceptions happen after my lock() in the synchronized block and before my calling notifyAll(), how should I deal with it, putting the notifyAll in a finally?
Thanks.
Andrew Monkhouse
author and jackaroo
Marshal Commander

Joined: Mar 28, 2003
Posts: 11279
    
  59

Hi Peter,
There are two possible scenarios that I think you could be asking about here.
  • The thread updating the record dies for some reason, sometime after the call to lock() but before the call to unlock().
    Before going into that, I would have to find out whether that thread that calls lock() .... update(), unlock() is on the client or the server. (In other words, are we talking about you handling the client/network crashing, or are we talking about your server thread crashing).
  • Two threads try to lock a record. The first thread deletes the record. What happens to the other thread?
    In that case you have to ensure that the record is unlocked after the delete occurs. So you might want to consider breaking your current unlock() method into two parts - one part which can do the verification on whether the record is valid or not, and another (private method) part which does the actual unlocking and calls notifyAll(). So delete() could then call that private method.


  • Does this make any sense, or have I talked about two issues that you didnt even want to discuss yet?
    Regards, Andrew


    The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
    Vlad Rabkin
    Ranch Hand

    Joined: Jul 07, 2003
    Posts: 555
    Hi Peter,
    Please pay very big attention to the point 2, mentioned by Andrew.
    Don't forget to check if a record still exists after you acquired the lock.
    Otherwise, you will get the lock on the record which doesn't exist.
    Any attemt to update such a record will cause RecordNotFoundException to be thrown, while record is still locked... (It will lead to the DEADLOCK)
    Best,
    Vlad
    [ October 28, 2003: Message edited by: Vlad Rabkin ]
    Philippe Maquet
    Bartender

    Joined: Jun 02, 2003
    Posts: 1872
    Hi Peter,
    Andrew:
    Two threads try to lock a record. The first thread deletes the record. What happens to the other thread?
    In that case you have to ensure that the record is unlocked after the delete occurs. So you might want to consider breaking your current unlock() method into two parts - one part which can do the verification on whether the record is valid or not, and another (private method) part which does the actual unlocking and calls notifyAll(). So delete() could then call that private method.

    Check if your unlock() method throws RecordNotFoundException. Mine not. It means that in my case, unlock() may safely be called after delete(), like here :

    Vlad:
    Don't forget to check if a record still exists after you acquired the lock.
    Otherwise, you will get the lock on the record which doesn't exist.

    In lock() method, I do like Vlad suggests :

    Best,
    Phil.
    Yuan Ye
    Ranch Hand

    Joined: Mar 05, 2003
    Posts: 172
    Hi, guys, Thanks for your responses.
    I have modified my design according to your points:
    a) In lock() method, I agree I must check the validity of a record after I have acquire the lock of that record. So I moved my check() after wait() method. Now I am sure my locking on an exist record. Thanks.
    b) All my lock and unlock are done in the server side. I have made sure that once a method get a lock, no RecordNotFoundException can be throw before uplock method (by synchronized method), so I didn't put my unlock() method in a finally block.(which can meanwhile prevent incorrect unlock) But as Andrew points out, what if a server thread crash before unlock()? I think the possibility is very small and itself is a disaster, so I don't need to consider this case. Could I just explain it in my design file?
    Waiting for your opinion.
    Yuan Ye
    Ranch Hand

    Joined: Mar 05, 2003
    Posts: 172
    Hi Phil

    In your code, would there be a problem if a exception is thrown in your lock(); and in fact the lock() didn't lock. Then your finally will be executed anyway, unlocking another thread's lock? Is that possible? In my implementation of lock/unlock, I used a static vector, I think it would be a problem for mine.
    Philippe Maquet
    Bartender

    Joined: Jun 02, 2003
    Posts: 1872
    Hi Peter,
    In your code, would there be a problem if a exception is thrown in your lock(); and in fact the lock() didn't lock. Then your finally will be executed anyway, unlocking another thread's lock? Is that possible? In my implementation of lock/unlock, I used a static vector, I think it would be a problem for mine.

    Good point. But in fact, unlock() would not unlock another thread's lock, a SecurityException would be thrown in unlock() instead, which is the normal use of that exception in this context.
    Now I have two overload isLocked() methods, one of them testing if some client owns a lock :
    (Don't be scary because of its weird signature : my LockManager class supports multiple tables and tracks locks owners.)

    I could use it in the finally block to conditionally call unlock().
    Thank you to have pointed that out.
    Best,
    Phil.
    Svetlana Koshkina
    Ranch Hand

    Joined: Jul 08, 2003
    Posts: 108
    To lock-unlock records dynamically two poss:
    first, you can stipulate in your docs that no record is to be deleted or added while the system is not in special (maintenance) mode (so i hope);
    second, all those rare conditions given, you have to wait:
    in process of doing such and such -wait, once have a chance to delete(add) the record from any data structure you are keep it in.
    'doing such and such ' is a state that can be evaluated to boolean. For ex., your system is in process of locking or unlocking or whatever. How you determine it is up to you. Without it you will get NullPointerEx or deadlock all the time you subject your system to good testing.
    Hope this help
     
    I agree. Here's the link: http://aspose.com/file-tools
     
    subject: two questiones about synchronized block.
     
    Similar Threads
    NX: RandomAccessFile / Singleton DataSchema
    pls validate my locking strategy - all inputs are g8ly appreciated. (URLyBird)
    My Locking...Advice needed...
    testing concurrency and sleeping threads
    NX: URLYBird / my approach of the reading problem