在我的例子中是java锁+HasMap还是ConcurrentHashMap?
我有一个Map<String, Queue<?>>
,每次我必须放入一对(键,值),我需要获取与该键关联的非线程安全队列,并向其添加一个值(如果键存在)。因为我需要更新现有的值(队列),所以我认为最好的方法是使用ReentrantLock(Java中的synchronized块或synchronized(object))<;1.5)而不是ConcurrentHashMap
这是正确的还是我可以使用ConcurrentHashMap而不是HashMap+Lock?我认为ConcurrentHashMap在get操作中更有效,但我不知道这是否是正确的解决方案
private static ReentrantLock lock_Vqueue = new ReentrantLock();
private static HashMap<String,Queue<DocumentObjectHolder>> cacheData = new HashMap<String,Queue<DocumentObjectHolder>>();
/**
* insert element in the tail
* sort the elements by priority
* @param obj a DocumentObjectHolder Object
*/
public static void add(String key, DocumentObjectHolder obj){
ReentrantLock lock = lock_Vqueue; //performance side effect
try{
Queue<DocumentObjectHolder>priorityProcessingVirtualQueue;
lock.lock();
if (!cacheData.containsKey(key)){
priorityProcessingVirtualQueue = new PriorityQueue<DocumentObjectHolder>(1, new PriorityComparator());
cacheData.put(key, priorityProcessingVirtualQueue);
}
priorityProcessingVirtualQueue = cacheData.get(key);
priorityProcessingVirtualQueue.add(obj);
cacheData.put(key, priorityProcessingVirtualQueue);
}finally {
lock.unlock();
}
}
/**
*
* @return DocumentObjectHolder instance from head of list (FIFO)
*/
public DocumentObjectHolder get(String key){
ReentrantLock lock = lock_Vqueue; //performance side effect
Queue<DocumentObjectHolder>priorityProcessingVirtualQueue;
try {
lock.lock();
if (cacheData.containsKey(key)){
priorityProcessingVirtualQueue = cacheData.get(key);
return priorityProcessingVirtualQueue.poll();
}
return null;
}finally{
lock.unlock();
}
}
}
这段代码是正确的还是性能更好
# 1 楼答案
所以你有两个独立的原子指令需要同步
以下是我的建议
继续使用
ConcurrentHashMap
。您仍然需要put
进入地图,您还可以使用CHM安全地完成使用
BlockingQueue
。在这种情况下,您可以使用PriorityBlockingQueue
如果无法执行(2),则从映射中对队列执行
synchronize
So 1&;3看起来像:
1&;2是
synchronized
的缺失我们之所以知道这是线程安全的,是因为即使有两个或多个线程进入
if(queue == null)
,只有一个线程会在putIfAbsent
中成功。丢失的线程将分配queue
来等于成功放入的队列。如果一个线程获胜(queue==null为true),那么我们将把队列分配给我们创建的(我们是获胜线程)