• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • paul wheaton
  • Jeanne Boyarsky
  • Ron McLeod
Sheriffs:
  • Paul Clapham
  • Liutauras Vilda
  • Devaka Cooray
Saloon Keepers:
  • Tim Holloway
  • Roland Mueller
Bartenders:

two questiones about synchronized block.

 
Ranch Hand
Posts: 172
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Bartender
Posts: 1872
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 172
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
author and jackaroo
Posts: 12200
280
Mac IntelliJ IDE Firefox Browser Oracle C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
     
    Ranch Hand
    Posts: 555
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    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
    Posts: 1872
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    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
    Posts: 172
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    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
    Posts: 172
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    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
    Posts: 1872
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    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.
     
    Ranch Hand
    Posts: 108
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    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
     
    If you're gonna buy things, buy this thing and I get a fat kickback:
    Smokeless wood heat with a rocket mass heater
    https://woodheat.net
    reply
      Bookmark Topic Watch Topic
    • New Topic