• Post Reply Bookmark Topic Watch Topic
  • New Topic

Sync Question

 
Dilip kumar
Ranch Hand
Posts: 360
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi, I'm writing a RMI based client server application. The client allows to
read and update records. I'm writing lock and unlock methods that so that
only one client can update a particular record at a time.
At server I'm having vector to hold locked records. My original plan was to
synchronize LOCK and UNLOCK methods. But I thought this is not a good
design. Consider the following situation :
1. Client A wants to lock record 1
2. Client B wants to lock record 2
Why should Client B wait until Client A completes Locking process
though Client B wants to lock different record ?
So I'm thinking of having lock on each object in the vector instead of
synchronizing LOCK & UNLOCK methods. But confused about logic.
I REALLY APPRECIATE SOME IDEAS / SUGGESTIONS..
Thanks
 
Peter den Haan
author
Ranch Hand
Posts: 3252
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Dilipkumar Kalyankar:
Hi, I'm writing a RMI based client server application. The client allows to read and update records. I'm writing lock and unlock methods that so that only one client can update a particular record at a time.

SCJD, right? You know there's a special JD forum?
At server I'm having vector to hold locked records.

This is not what you were asking, but -- why a Vector?

  • A Vector is a synchronized data structure. Yet you will find that this is not enough, you will have to add your own synchronization anyway. An unsynchronized data structure from the Collection classes would be more appropriate, like an ArrayList, but:
  • Analyse your usage pattern and you will find that it is not ideally suited to an array-backed structure. A linked list would perform better (O(1) for deletions instead of O(n)). Except:
  • You will want to know as quickly and efficiently as possible whether a given record has already been locked. The last thing you want to do is an O(n) search through all the locks. Moreover, you can lock any given record only once, which suggests a Set or Map. A HashSet or HashMap would give you O(1) performance.

  • In the SCJD you really have to know your data structures.
    My original plan was to synchronize LOCK and UNLOCK methods. But I thought this is not a good design. Consider the following situation :
    1. Client A wants to lock record 1
    2. Client B wants to lock record 2
    Why should Client B wait until Client A completes Locking process
    though Client B wants to lock different record ?

    Unless you want to use, say, an array with one object for each record (not a good idea if you want to scale to arbitrarily many records), the locks will inevitably be part of a single complex data structure. Which means that, whatever you do, you will have to synchronize access to the shared parts of this data structure.
    If access to this shared part takes a small and bounded amount of time, that's quite alright. What you don't want, of course, is a client waiting for a lock blocking access to locks on other records. Object.wait() and Object.notify()/notifyAll() have been created with this kind of situation in mind.
    - Peter
 
Dilip kumar
Ranch Hand
Posts: 360
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Peter,
I know there is specific forum for JD ( and I do post questions there ! ). Since I had doubt about synchronization I thought I this forum may be the suitable one.
Regarding maintainingg single objects for each record, you are absolutely right. This may not be a good design for large number of records.
Thanks again. Your explaination is good ( I think I posted my question in appropriate forum !).
Dilip
[This message has been edited by Dilipkumar Kalyankar (edited April 15, 2001).]
 
Peter den Haan
author
Ranch Hand
Posts: 3252
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Apologies, Dilip, if I seemed to imply that this was not an appropriate forum. I think it is. Just didn't know if you'd discovered the SCJD forum.
When I did my SCJD, I think clients synchronized on a HashMap, and would wait() on that if they could not obtain their lock. A client releasing a lock would notifyAll().
Come to think of it, if you have an object representing a lock, you can synchronize on that object and wake up a client which is specifically wait()ing for that single lock. You would still have to synchronize on the shared structure when adding or deleting locks of course.
- Peter
 
Dilip kumar
Ranch Hand
Posts: 360
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Peter,
No need to apologize. I think there was minunderstanding between us regarding JD forum.
Regarding synchronizing objects, some authors do not prefer synchronizing on objects other than "this". So I'm wondering whether I should synchronize my lock / unlock methods or synchronize Hashmap/ Hashset. Any suggestions ?
Thanks
[This message has been edited by Dilipkumar Kalyankar (edited April 15, 2001).]
 
davidlong
Greenhorn
Posts: 21
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Dilipkumar
Peter is right. you get to be synchronize the data structure, not the method(lock/unlock). The reason is if you synchronized on metnod, then you actually put lock/unlock methods into the same monitor as all public methods in Data class except you create a inner class to hold the lock/unlock methods, thus never have the effect of different record having its own lock.
But you could still use the Vector to hold the record lock, the vector is a synchronized data structure, it is thread-safe and will save you a lot if you use proporly. In matter fact, I used the Vector to store the locks in my SCJD assignment, and get a good score on it.
The critical points about the implementation of lock/unlock is that you must make locks data threads-safe, and could be unlocked even the exception occured.
David
 
Peter den Haan
author
Ranch Hand
Posts: 3252
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by davidlong:
But you could still use the Vector to hold the record lock, the vector is a synchronized data structure, it is thread-safe and will save you a lot if you use proporly.

Yes, a Vector may save you typing "synchronized" here and there. But more often than not it lures hapless developers into thinking they're "safe", blinding them to dangerous (and very hard to detect) race conditions in their code. A simple example:

Even if "locks" is a Vector, this code is not threadsafe. (It also demonstrates that a Vector or ArrayList perform O(n) and are not the best choice, but that's beside the point).
So even with a Vector or any other synchronized object you will have to carefully go through it method by method and determine which parts should execute atomically, i.e. be protected by a synchronized block. And you may find yourself synchronizing so much that the synchronization within the Vector is really unnecessary (and only slows the application down).
In matter fact, I used the Vector to store the locks in my SCJD assignment, and get a good score on it.

98% (151/154), no Vector
- Peter

[This message has been edited by Peter den Haan (edited April 17, 2001).]
 
Dilip kumar
Ranch Hand
Posts: 360
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Is there any advantage if we use
Set s = Collections.synchronizedSet(new HashSet(...));
along with synchronizing lock and unlock methods ?
I'm plannign to define synchronized lock & unlock methods in helper class avoiding more sync methods in Data class.
Thanks
 
Peter den Haan
author
Ranch Hand
Posts: 3252
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by david long:
Look at your sample code. What was your trying to say?, What a stupid code, you are really know nothing about how to use the advantage of the Vector - the synchronized data algorithm, do you?

That code was there to illustrate a point, not to be particularly intelligent - quite the opposite, I should say. (The point being that the threadsafe nature of a Vector makes it tempting to use logic which looks reasonable, but is not threadsafe at all.) Until you demonstrate why it fails in that purpose, you might want to keep your opinions to yourself. Thank you.
- Peter
 
Peter den Haan
author
Ranch Hand
Posts: 3252
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Dilipkumar Kalyankar:
Is there any advantage if we use
Set s = Collections.synchronizedSet(new HashSet(...));
along with synchronizing lock and unlock methods ?

The proof of the pudding is the eating - try it. It's not as if it is masses of code (if it is, it's time for refactoring); you will spend 90% of your time thinking about the problem and these thoughts are perfectly re-usable
What you will find, once you have carefully eliminated all race conditions, is that you will be doing a fair bit of the synchronization explicitly. The consequences are, in order of importance: first, the fact that synchronization sits in two places (the synchronized Set and your own code) makes your logic less explicit. Second, you will probably have discovered code which looked fine at the time of writing but was in fact thread-unsafe. Third, monitor locks are sometimes acquired twice, once in your own code and again in the Set. This is less than optimal, but admittedly not a problem in practical terms.
For me, these would be reasons enough to take the plain unsynchronized Set and carefully synchronize the lock manager wrapped around it.
- Peter

[This message has been edited by Peter den Haan (edited April 18, 2001).]
 
david long
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Peter
I just do not understand why you give that code to improve yourself understanding the Vector tread-safe. How did you know people will mis-use the code like that to claim its thread safe for locks. Obviously, you mis understanding the meaning of thread safe of Vector.
Remmber this point. When we say a Vector thread safe, it means the data stored in vector a thread safe, do not expands the idea to outside Vector, Ok. It do not mean the lock/unlock the database a thread safe, which depends on how you apply the lock/unlock on database. However it is first step to make your locks data thread safe, which have many ways and someone may code two idea together while someone not.
If you try to claim your code on whole data base to impove your point(un-threadsafe vector), then you mixture the vector thread safe with database thread safe. If not, I really do not understanding what you trying to say.
You really do not understanding how was the vector collection sun created for, you expend vector too much to claim your point, that was really ashame.
David
 
Peter den Haan
author
Ranch Hand
Posts: 3252
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by david long:
I just do not understand why you give that code to improve yourself understanding the Vector tread-safe. How did you know people will mis-use the code like that to claim its thread safe for locks.

Ummm, because I've seen it happen often enough? Maybe?
Obviously, you mis understanding the meaning of thread safe of Vector.
Remmber this point. When we say a Vector thread safe, it means the data stored in vector a thread safe, do not expands the idea to outside Vector, Ok.

David, what exactly did you think my point was?
[...] However it is first step to make your locks data thread safe

No. Thread safety is not about using synchronized objects everywhere. In general, doing so tends to ruin the scalability of your application and invite deadlocks (if you use callbacks). In this particular case, I contend that the thread-safety of the Vector does not help you and may even work to your detriment.
- Peter
 
Ganapathi Srinivasan
Ranch Hand
Posts: 41
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi peter..
Even though I am a bit late into this discussion as to whether Vectors are thread safe or not...I totally agree to your point. It is out of a bitter experience that i had faced last week.
In one of our programs(threaded one) there were terrible deadlocks and upon performing a detailed surgery into the code we found out that the real culprits were the vectors that we were using. We were of the thinking that vectors were thread safe and so we did not synchronize the vector.addElement() and elementAt() calls. But upon putting a synchronized block on the respective vector, we have indeed resolved the problem.
Thanks for your timely help.
Regards,
Ganp.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!