有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java最佳集合,用于多线程中相同数量的添加、读取和删除,其中一个线程添加,另一个线程读取,从同一存储中删除

我想存储数据(主要是通过单个线程一个接一个地完成)。 然后,我想获取存储的数据,如果找到,则在处理找到的对象以供本地使用后,将其从存储中删除。此操作(读取和删除)将由多个线程完成,其中每个线程将执行多次(因为每个线程将执行许多步骤,每个步骤都需要从存储器中读取,如果找到,则在复制后删除找到的对象。对于每个线程,此读取和删除即步骤的执行将是连续的)

目前,我已经创建了hashmap(String,CopyOnWriteArrayList),用于存储值,因为类似的键可以包含多个相关值

对于每个键,CopyOnWriteArrayList对象可以存储超过200000个值。因此,至少要进行200000次写入和删除,在删除之前,需要根据匹配条件从列表中提取值

由于读取和获取+删除是分开完成的,因此我无法在一个位置锁定/同步列表

当写入、读取和删除的次数增加时,性能会变慢,我认为这主要是由于使用了CopyOnWriteArrayList

Imp:与每个键的值(列表大小)相比,键的数量将非常少。e、 g.列表中可以有10个键,但每个键可以包含100000个值

请推荐最好的替代品

这是密码

storeMessage方法仅由一个线程调用,但retrieveMessage方法由多个线程使用

private static Map<String, MessageCache> cacheMap = new HashMap<String, MessageCache>();
public void storeMessage(MyObject message) {
    MessageCache messageCache = null;
    synchronized (cacheMap) {
                    if (cacheMap.containsKey(cacheIdentifier)) {
                        messageCache = cacheMap.get(cacheIdentifier);
                    } else {
                        messageCache = new MessageCache(isTrue);
                        cacheMap.put(cacheIdentifier, messageCache);
                    }
                }
    messageCache.storeMessage(message);
}

public MyObject retrieveMessage(MyObject searchMessage) {
    if (cacheMap.containsKey(cacheIdentifier)) { //cacheIdentifier is the key
            return cacheMap.get(cacheIdentifier).retrieveMessage(searchMessage);
    }
}

private class MessageCache {
    private List<MyObject> messageList = new CopyOnWriteArrayList<MyObject>();
        private boolean requestCache;

        public MessageCache(boolean requestCache) {
            this.requestCache = requestCache;
        }
        public void storeMessage(MyObject message) {
            messageList.add(message);
        }
        public MyObject retrieveMessage(MyObject searchMessage) {
            if (requestCache) { 
                    try {
                        synchronized(this){//This has been done to avoid getting same values from the list
                            for (MyObject storedMessage : messageList) {
                                if (match) {
                                    messageList.remove(storedMessage);
                                    return storedMessage;
                                }
                            }
                        }
                    }catch (Exception e) {}
            }else{
            }
        }
}

共 (1) 个答案

  1. # 1 楼答案

    根据您所说的,听起来像是一个并发队列,而不是HashMap(比如LinkedBlockingQueue或(我认为它会更好)^{})最适合那里

    首先,创建一个包含两个私有变量的新类:

    class maps{
    
    private String key;
    
    private MessageCache data;
    
    maps(String key, MessageCache data){
    
        this.data = data;
    
        this.key = key;
    
    }
    
    public String getKey() {
        return key;
    }
    
    public MessageCache getData() {
        return data;
    }}
    

    然后,在CurrentLinkedQueue中使用这个类:CurrentLinkedQueue<maps> clq = new CurrentLinkedQueue<>();

    要获得密钥,请使用:

    Iterator<maps> i = clq.iterator();
    
        while(i.hasNext()){
    
            maps m = i.next();
    
            m.getKey(); //use the String varible this statement return in the part of your code where you need to process the key.
                        //if you need to remove that element use i.remove();
    
    
        }
    

    另一种解决方案是创建CurrentLinkedQueue并将集合的索引用作键

    作为旁注,请查看Java Concurrency explanations。它可能会帮助您理解为什么使用这种类型的集合更好,以及在Java中并发是如何工作的