我知道经常会问类似的问题,但我找不到任何可以帮助我的事情。
情况是这样的:
问题是:如何复制(我认为最好是复制)第二个工人的集合,然后清除原始集合以确保我们不会丢失任何东西(第一个工人一直在写)但是不要尽可能地锁定原始收藏品?
感谢
答案 0 :(得分:8)
如果您使用专用的并发工具(如LinkedBlockingQueue
而不是普通的HashSet
),这种事情会容易得多。让生产者向队列添加元素,并且消费者可以使用drainTo
按需要批量提取队列中的元素。不需要任何同步,因为BlockingQueue
实现被设计为线程安全。
答案 1 :(得分:0)
Ian的LinkedBlockingQueue
解决方案是最简单的。
对于单个生产者单个消费者场景中的更高吞吐量(可能与延迟权衡),您可能需要考虑java.util.concurrent.Exchanger
交换后,您现在可以自己拥有整个系列。
答案 2 :(得分:0)
如果有多个生产者在某个时间段内产生许多重复值 - 您可以尝试使用 ReadWriteLock,因为只要没有写入者,读取锁可能会被多个读取器线程同时持有。写锁是独占的。
即使在 readLock 内部,我们也在做写操作,但它仍然有效。更改名称或实现您自己的一对关联锁。
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class MyClass {
private final Map<String, Integer> cachedData = new ConcurrentHashMap<>();
private final ReadWriteLock lock = new ReentrantReadWriteLock();
private final Lock readLock = lock.readLock();
private final Lock writeLock = lock.writeLock();
public void putData(String key, Integer value) {
try {
readLock.lock();
cachedData.put(key, value);
} finally {
readLock.unlock();
}
}
public Collection<Integer> copyAndFlush() {
try {
writeLock.lock();
Collection<Integer> values = cachedData.values();
cachedData.clear();
return values;
} finally {
writeLock.unlock();
}
}
}