Lets say i've got a simple Map which is queried frequently, but only very occasionally modified. Currently I am using synchronized blocks to protect against race conditions when adding to the map (simplified example):
public class MyRepository {
private static HashMap<Integer, Object> MAP = new HashMap<Integer, Object>();
public static Object getInstance(Integer key) {
synchronized (MAP) {
return MAP.get(key);
}
}
public static void addInstance(Integer key, Object instance) {
synchronized (MAP) {
MAP.put(key, instance);
}
}
}
I left out any application specific crap like dealing with key collisions etc. You get the picture, very simple. During runtime, the map is filled with instances when the application starts up. After that the map is rarely ever modified (once in a blue moon, so to say). On the other hand, the map is queried quite often, and multiple threads querying the map are开发者_JS百科 blocking each other.
Is there a protection mechanism that allows multiple "readers" to get hold of the map concurrently while still allwing only one "writer" at a time?
Have you looked ad ConcurrentHashMap from JDK 5? It is meant for this usecase
How about a ReadWriteLock?
ConcurrentHashMap is likely to be your best solution. However if writes are very rare, you could maintain two copies, a master copy which you synchronise and and a second map which is a copy which is replaced every time you change the first map. This makes writes very expensive but reads as cheap as not having any locking.
精彩评论