Win a copy of Cross-Platform Desktop Applications: Using Node, Electron, and NW.js this week in the JavaScript forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Help me get this work  RSS feed

 
Maulin Vasavada
Ranch Hand
Posts: 1873
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi all,

Following is my scenario,

- I have a list of Strings (actually file names with complete path) in an object X. X is Stateless Singleton.

- I have methods acquireLock(String filepath) and releaseLock(String filepath) in X

- Every thread calls acquireLock() on a file and MUST call releaseLock() before anybody else can acquire lock. So you can assume that client threads have code that is something like-
....acquireLock()
....doSomething()
....releaseLock()

- I don't want to synchronize on whole list. The reason is, if I get two parallel requests path1/file1 and path2/file2 I know that they can be handled in parallel as base paths- path1 and path2, are different. In the list I would have {path1/file1,path2/file2,...}. Now, if I synchronize on the whole list then what will happen at some point is- if Thread1 has locked the list for path1/file1 then NO OTHER thread can proceed even if they have different requests path2/file2, path-N/file-N etc...
HOW CAN I AVOID THIS HAPPENING?

MY PROBLEM in the sample code:
------------------------------
- I wrote sample code to simulate this behavior for testing. I thought that if I use String.intern() method which gives the same reference for the Strings which are actually constants and equal then it would work.

- I customized HashMap as shown and tried to put synchronization on Key's intern() method (You can assume that I have string type Keys) but it doesn't seem to work

Code-


At some point in the Output I see,
Thread One putting (keyA,valA)
Thread Two putting (keyA,valA)
(or keyB,valB you know)...

- I have made sure by flushing streams that I don't have "just printing problem". So there is some serious problem in the code.

Can anybody help me solve this? I have put Synchronization on the whole List for now to make it work but I wish I can get this working...

Please feel free to ask more questions if this is unclear.

Regards,
Maulin
[ September 03, 2004: Message edited by: Maulin Vasavada ]
 
Maulin Vasavada
Ranch Hand
Posts: 1873
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi all,

Okay. I think that "spurious thread wake up" is causing this problem.

Though I use Java1.4 API, which doesn't say anything about Spurios Wake ups as Java 1.5 API it happens

So, now in put() method I have put while loop for wait as,

while(super.get(key) != null ) {
s.wait();
}

And that seems to work.

Thanks
Maulin
 
Stan James
(instanceof Sidekick)
Ranch Hand
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Can you do something as simple as:

If two threads got the same lock object at the same time, one would have to wait until the other was finished. The lock object could be anything, maybe just a String with the name of the file.
 
Maulin Vasavada
Ranch Hand
Posts: 1873
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Stan

How would we implement StaticClass.getLockFor("name") ? In the StaticClass we might have some HashTable holding {name,lock} pairs right? But the problem is we have to synchroniz access on the whole HashTable there, right? Which is what I want to avoid as I "know" that there would be contention for common "name" and I need to only lock one particular HashTable entry for multiple threads than the whole Table.

Thats why I have extended HashMap and overridden put which synchronizes on one key

You see what I am trying to point out?
 
Stan James
(instanceof Sidekick)
Ranch Hand
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
We have two issues.

One is to prevent thread problems with get, add, remove, etc. We might want to synchronize the collection - see Collections.synchronizedMap() rather than writing your own. Get is fairly fast, so it probably wouldn't be a big problem to synchronize the whole collection if that's the main activity.

The other issue is to synchronize access to a file. For that your synchronized block can lock on the object stored in the collection, not on the collection. Can you give it a try? I'd be interested in how it works for you.
 
Maulin Vasavada
Ranch Hand
Posts: 1873
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Stan,

I don't want to synch whole Collection otherwise I better go with synchronizedMap() thing you suggested. So first issue is not issue for me.

For second one you mentioned,

The other issue is to synchronize access to a file. For that your synchronized block can lock on the object stored in the collection, not on the collection.

So you understand what I am trying to do there and thats what I have done in my code which I have posted. I am synch on the object stored in the Collection that is "key names".

I will let the Collection being asynch as I dont mind parallel access to that. There won't be any issue if I have 10 threads trying access key1 and 20 other contending for key2 simultaneously BUT I do have to make sure that any particular key's access is synch amongst requesters....

Can you see my code again and see what I am trying to do and how it matches what you have suggested?

Regards,
Maulin
 
Maulin Vasavada
Ranch Hand
Posts: 1873
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
okay...let me just post the code that works for me...look at it and see how it works. I don't think there is any bug in the synch code in that...if you find one please let me know...




Regards,
Maulin
[ September 07, 2004: Message edited by: Maulin Vasavada ]
 
Stan James
(instanceof Sidekick)
Ranch Hand
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The file modifiers can do this:

The static file lock holder can do this:

getLockFor is synchronized and forces all threads through one at a time, but it is a relatively fast method. I think you might have to leave the locks in the map forever. Any thoughts on when it would be safe to remove them?

Hmmmm, maybe you could count concurrent lock holders and remove from map when count goes to zero. (Any number of objects can acquireLock, but only one can access the file at a time. There could be a pile of them waiting to run.)

and

This exposes you to risk from bad clients who acquire and forget to release!

Any of that help?
 
Stan James
(instanceof Sidekick)
Ranch Hand
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Forgot to say -- JDK 1.5 (or is it 5.0) has classes to do this. Doug Lea's library has the same things for other JDK versions. Using one ofo those would be much safer than listening to me.
 
Maulin Vasavada
Ranch Hand
Posts: 1873
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Stan,

I have releaseLock() so at that time I remove locks from the Collection.

Btw, if I wanted to auto removal I would go with WeakReference I guess...

Now, back to my concern, in your code snippets you have provided you are having,
synchronized(map) // standard Map, not custom

Which I want to avoid doing. If we do that then "all the requests to all filenames" will synchronize. I want "all the request for particular filename" synchronize so I can have more threads working on different filenames...

Although, I noted your point that it might be equal faster to have whole Map Synchronize but you know sometimes I get just theoritical in practical world...

But thanks for detailed input so far. I have yet to look at jdk1.5 in more details...

Regards,
Maulin
 
Mr. C Lamont Gilbert
Ranch Hand
Posts: 1170
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am doing this exact thing with my code but for much different reasons

You are concerned with locking the map but you should not be. this is only a brief lock. You only hold it long enough to grab the other lock, you should not see much delay or contention with that lock. I can post an example of the class I use if you like.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!