Win a copy of Practical SVG this week in the HTML/CSS/JavaScript forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Shared cache

 
Amer Seifeddine
Ranch Hand
Posts: 57
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Folks,

I am wondering what would be the best practice for below scenario in java:
we have a shared object for accessing cache but rarely updated based on users action.. I know that usually, we have to synchronize both, get and set, methods.. However, this way we oblige other threads to wait to get the cache at the same time .. In other words, I m looking for a way to share get method with all threads and block it when we modify it.. then, notify all threads to continue once set method is completed.

Thanks!
 
Nicholas Jordan
Ranch Hand
Posts: 1282
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
One thing to look at for sure is the advice given in http://www.coderanch.com/t/233420/threads/java/Thread-Design to consider the Executor class. I can go read it if you want and provide my opinon, often these library designs offer proven track record.

Since changes to the pool of available response objects ( on the business app end ) are thread managed by the business app ( per post in performance ) we can examine letting all the sync() be done by the business app. Look at the docs for java.util.Collections so that I am not doing your work for you. There is a subtle timing condition that shows up in a well studied problem called "double checked singleton locking" that can be approached by individual record locking. It is emerging that what you are trying to accomplish is the dispatching of the request object to the business application. Maps key an object by design. Making one static Map that is accessed by a synchronized method ( static synchronized in the Map object, not the request instances ) is likely not a bottle neck if all that need be done is session key managment.

{ message edit: look at Package java.util.concurrent }
[ May 01, 2008: Message edited by: Nicholas Jordan ]
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Amer: if you're relying on synchronization at all, you will need to synchronize both getters and setters in order for the synchronization to be effective. Even if sets are comparatively rare. However there may be other options. If your cache works like a Map (using a key), then you might use a ConcurrentHashMap. This can be more efficient than a synchronized HashMap, with slightly different guarantees (e.g. if you need to iterate through the Map while items are being added). Read the API for this class carefully to see if it meets your needs.
 
Nicholas Jordan
Ranch Hand
Posts: 1282
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jim, one thing I wanted to get to is trying to think of ( for the poster ) a stochastic search paradigm to get away from a hard and fast seqential search for .nextAvaliable() that always starts at the same place. ( It may be that this is not necessary and has been explored in the dot concurrent packages - just thinking )

Also, I had in mind to suggest static synchronized acessor(boolean get); as the calling method for the Map.

{ message edit: Apparently the Bear has already done a lot of work on the issue the original poster is considering: JavaRanch Journal - Scriptless JSP Pages: The Power of the Map }
[ May 01, 2008: Message edited by: Nicholas Jordan ]
 
Amer Seifeddine
Ranch Hand
Posts: 57
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jim. This seems to be very close to what I am looking for. Thank you.
Do you know of a way to add concurrency to existing maps built by myself? Like, I made my own maps and hash it according to my needs.. they so not extend any of util classes but I need to add this feature to them.. do i need to implement an interface or rebuild it from scratch (or use existing standard ones for sure )?
 
Nicholas Jordan
Ranch Hand
Posts: 1282
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by amer seif el dine:
(...snip...)Do you know of a way to add concurrency to existing maps built by myself? Like, I made my own maps and hash it according to my needs.. they so not extend any of util classes but I need to add this feature to them..


See if you can subclass an existing dot concurrency class.



Implement an interface, or sublcass one in concurrency that already does. Look at it's implementation.

Jim likely has his own answer, this is just to provide addtional views for consideration.
 
Henry Wong
author
Sheriff
Posts: 22542
109
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by amer seif el dine:
Jim. This seems to be very close to what I am looking for. Thank you.
Do you know of a way to add concurrency to existing maps built by myself? Like, I made my own maps and hash it according to my needs.. they so not extend any of util classes but I need to add this feature to them.. do i need to implement an interface or rebuild it from scratch (or use existing standard ones for sure )?


The concurrent hashmap relies on data segmentation in order to allow writes to be done in parallel. And relies on reader writer locks to allow reads to be futher done in parallel.

Obviously, adding segmentation to your hashmap may require major refactoring, but it shouldn't be too hard to change your synchronizations to use the java util concurrent reader writer locks. Just have the get grab a reader lock, and the set grab a writer lock.

Henry
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Amer: well as Nick suggests, I'd usually try to use one of the library classes rather than writing my own, as it's usually less work. Even if they're already written, it's often not difficult to replace them with standard library implementations. In many cases, rather than extending a library class (like Map) as Nick suggests, I would probably make the Map an instance variable inside another class that controls access to it. Hard to say though without knowing more about your requirements.

Assuming there is some reason you really need to use your custom classes, the easiest solution may be to add synchronization to both getters and setters. If you use sync, you can't really omit it from the getters. Usually.

Alternately, since you say that set operations are rare, you might try implementing copy-on-write behavior. (This is an alternative to Henry's suggestions above, and I haven't fully thought through whether it will work.) This would mean that the getters can be unsynchronized, but not the setters. Whenever a setter is called, you would make a copy of the data structure, modify the copy, and then replace the original with the copy. The getters would never see the structure while it was being modified - you would just either get a view of the structure before modification, or after. You also might need to make one or more instance variables volatile for this to work correctly. I think this might be easier than the segmentation solution Henry suggests (and used by ConcurrentHashMap), but it's also probably slower. Which is probably why there's no CopyOnWriteHashMap. And it may just be that I haven't thought it through well enough, and there are other problems.
[ May 01, 2008: Message edited by: Jim Yingst ]
 
Nicholas Jordan
Ranch Hand
Posts: 1282
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Jim Yingst:
Amer: well as Nick suggests, I'd usually try to use one of the library classes rather than writing my own, as it's usually less work. Even if they're already written, it's often not difficult to replace them with standard library implementations. In many cases, rather than extending a library class (like Map) as Nick suggests, I would probably make the Map an instance variable inside another class that controls access to it. Hard to say though without knowing more about your requirements.


I had in mind the concurrency classes, for it's sync() already being subjected to field use. The map would be an instance variable as you suggest. I intended the accessor for the map ( and the map ) to be static synchronized, on the basis of postings in Performance. I just sorta gravitate toward map. OP has one other data structure in mind as primary candidate.

Assuming there is some reason you really need to use your custom classes, the easiest solution may be to add synchronization to both getters and setters. If you use sync, you can't really omit it from the getters. Usually.


A better description of the challenge is given in Performance, btw I found this a moment ago which seems relevant to OP's design challenge. http://java.sun.com/security/jaas/doc/pam.html

Alternately, since you say that set operations are rare, you might try implementing copy-on-write behavior. (This is an alternative to Henry's suggestions above, and I haven't fully thought through whether it will work.) This would mean that the getters can be unsynchronized, but not the setters. Whenever a setter is called, you would make a copy of the data structure, modify the copy, and then replace the original with the copy.


I thought about this also, that is where I came up with the static synchronized access, but the individual record would still have to have a lock - else we get compound data structures being written in the middle of a write. OP has to manage the logon, and pair it with a session id on a server that already has locking working. Design is to take local or remote requests from any linguistic and tie a session id from the server to the paticular request.


... You also might need to make one or more instance variables volatile for this to work correctly. I think this might be easier than the segmentation solution Henry suggests (and used by ConcurrentHashMap), but it's also probably slower. Which is probably why there's no CopyOnWriteHashMap. And it may just be that I haven't thought it through well enough, and there are other problems....


That is why I suggested to original poster to move the Threading issuse here.
 
Nicholas Jordan
Ranch Hand
Posts: 1282
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
[Henry Wong:]The concurrent hashmap relies on data segmentation in order to allow writes to be done in parallel. And relies on reader writer locks to allow reads to be futher done in parallel.

Session objects ( for posters design ) can be pooled before the request comes in, I do not see robust parallelizing as the primary design goal here. It is good practices, poster is trying to tie the server session to a session id generated with jsp. After that, it is dispatched. I saw some issues and directed those issues be worked here.

Obviously, adding segmentation to your hashmap may require major refactoring, but it shouldn't be too hard to change your synchronizations to use the java util concurrent reader writer locks. Just have the get grab a reader lock, and the set grab a writer lock.


Example: Access will be sycchronized only if they are subject to a modification.. am I RIGHT? Wrong. There are several issues, this should go here.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!