ConcurrentHashMap等待密钥可能吗?

Kad*_*SOL 3 java collections guava

我有多线程的沟通.1线程正在将数据分派给其他线程.

主线程正在推送数据:

主线程:ConcurrentHashMap map = Global.getInstance().getMap(); //将数据推送到其他线程map.put(1,"Test");

线程1:字符串数据= map.get(1); //直接返回null,但我想等到推送数据

如果主线程没有推送任何数据,则线程1返回null.但我想等到有数据,我该怎么办?

TransferQueue不是我当前实现的好方法.我必须使用ConcurrentHashMap.

有人知道任何解决方案吗?

m3t*_*man 5

你可以创建一个像这样的BlockingMap; 根据使用情况,您还应该设置一种机制来删除与其关联的未使用的密钥和队列,以避免内存泄漏.

public class BlockingMap<K, V> {
    private final Map<K, BlockingQueue<V>> map = new ConcurrentHashMap<>();

    private synchronized BlockingQueue<V> ensureQueueExists(K key) {
        //concurrentMap.putIfAbsent would require creating a new
        //blocking queue each time put or get is called
        if (map.containsKey(key)) {
            return map.get(key);
        } else {
            BlockingQueue<V> queue = new ArrayBlockingQueue<>(1);
            map.put(key, queue);
            return queue;
        }
    }

    public boolean put(K key, V value, long timeout, TimeUnit timeUnit) {
        BlockingQueue<V> queue = ensureQueueExists(key);
        try {
            return queue.offer(value, timeout, timeUnit);
        } catch (InterruptedException e) {
            throw new IllegalStateException(e);
        }
    }

    public V get(K key, long timeout, TimeUnit timeUnit) {
        BlockingQueue<V> queue = ensureQueueExists(key);
        try {
            return queue.poll(timeout, timeUnit);
        } catch (InterruptedException e) {
            throw new IllegalStateException(e);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

从Java 8开始,ensureQueueExists可以编写:

private synchronized BlockingQueue<V> ensureQueueExists(K key) {
    map.computeIfAbsent(key, k -> new ArrayBlockingQueue<>(1));
}
Run Code Online (Sandbox Code Playgroud)


Alv*_*son -1

首先,wait()在线程 1 从 Map 获取值之前调用它。然后,您可以扩展 ConcurrentHashMap 并在新数据可用时将该put()方法重写到线程 1。notify()

  • 通过这种方法,您可以同步两个线程。如果你的两个头会互相阻塞,那么使用 ConcurrentHashMap 有什么意义呢? (2认同)