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

Notify, wait, read, write

 
Stephen Galbraith
Ranch Hand
Posts: 90
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi everyone,
I think I'm going mad!
I had implemented locking etc in a similar fashion to that advocated in Max's book. However, due to recent spate of people getting 40/80 on their locking I began to panic about the words in the instructions "consuming no cpu cycles".
Now I'm thinking about changing to something along the lines of (Note theLM is a static LockManager class)

I've given it a go and it seems okay - where are the flaws?
Having refactored this way should I tackle the write to just sync on the individual object as well (thus allowing multiple threads to access different parts of the db simultaneously)?
I'm also getting paranoid about syncing too much. Hence I'm thinking about having the read (& find) methods unsync'd allowing "dirty" reads of the db.
What do you think? A bridge too far? Have I lost it?
Input appreciated, especially today - it's already been too long!
Thanks
Steve
 
Stephen Galbraith
Ranch Hand
Posts: 90
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
No reviewers?
Have I annoyed everyone?
 
Henrik Lund
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Stephen,
I think your solution is a good one. I've implemented a very similar solution and I can't see any major drawbacks.
The only minor(?) drawback I can think of is how to limit the size of the shared data structure in LockManager (that holding the lock objects). I haven't been able to find a thread-safe way of getting rid of unused objects. I've tried to delete it from LockManager.unlock but found some multi-threading problems. Thus, with really large databases, my data structure will continue to grow for each unique processed record number. But that's my problem. Maybe your design avoids this drawback.
Maybe a WeakHashMap does the trick...
Regards,
Henrik
[ February 05, 2004: Message edited by: Henrik Lund ]
 
Andrew Monkhouse
author and jackaroo
Marshal Commander
Pie
Posts: 12014
220
C++ Firefox Browser IntelliJ IDE Java Mac Oracle
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Stephen,
Looks pretty good to me.
Having refactored this way should I tackle the write to just sync on the individual object as well (thus allowing multiple threads to access different parts of the db simultaneously)?

Personally I don't see a lot of value in this unless you had multiple RAF objects. Even then your performance gain will be minimal.
Regards, Andrew
 
Stephen Galbraith
Ranch Hand
Posts: 90
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks all,
much more confident now I guess I had the mid-week blues!
Henrik,
I haven't avoided this "growing" issues either, not yet anyway!
Andrew,
thanks for the "leave it alone" advice - I think I'll take it!
Thanks again,
Steve
 
Philippe Maquet
Bartender
Posts: 1872
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Henrik and Stephen,
Henrik:
The only minor(?) drawback I can think of is how to limit the size of the shared data structure in LockManager (that holding the lock objects). I haven't been able to find a thread-safe way of getting rid of unused objects. I've tried to delete it from LockManager.unlock but found some multi-threading problems. Thus, with really large databases, my data structure will continue to grow for each unique processed record number. But that's my problem. Maybe your design avoids this drawback.

Stephen:
I haven't avoided this "growing" issues either, not yet anyway!

If you put your recObjects per recNo in a LinkedList and store that LinkedList in some HashMap (one entry per record):
  • It solves your issue because when such a LinkedList becomes empty you may remove the entry in the HashMap
  • You get for free locks granted in FIFO order which can be desirable.


  • Best,
    Phil.
    [ February 06, 2004: Message edited by: Philippe Maquet ]
     
    Henrik Lund
    Greenhorn
    Posts: 9
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I just implemented an solution with reference counting. It works like this: each shared record number object got a reference count. This count is increased before lockRecord and decreased after method completes. The unlock method also increases the count and decreases it after completion. The decrease in unlock check for the possiblitiy that the ref. count is zero. If it is, the shared lock object is removed. I think the complexity is rather low, LockManager class is 250 LOC (with extensive commenting).
    In code it looks like:

    The lockRecord(p_recNo, t_lockRec) method is implemented as "usual", but synchronize on the t_lockRec instance instead of a shared HashMap (to name one possibility).
    The unlock method is very similar to the code above.
    I've tested this code with 30+ concurrent threads performing lock/unlock. It seems to perform nicely. The "growing issue" is solved.
    Regards,
    Henrik
     
    • Post Reply
    • Bookmark Topic Watch Topic
    • New Topic