我正在寻找一个线程安全的 BloomFilter 实现,即,如果将值按顺序或同时并行放入过滤器,则该实现的行为将完全相同。番石榴的 BloomFilter 的 javadoc 对线程安全保持沉默。它是线程安全的吗?
5 回答
番石榴BloomFilter
不是线程安全的。
也就是说,我并不是 100% 清楚你期望线程安全的语义是什么BloomFilter
——put
是原子的?我在想象long[]
用 an替换的效果AtomicLongArray
,我很确定你最终得到的语义是“如果put(x)
发生在之前mightContain(x)
,则mightContain(x)
返回true
”,我认为这些语义很有用,但我并不积极。
这可能值得提出一个特定用例的问题,但是会有一些细节来弄清楚线程安全在这里究竟意味着什么。
正如其他人所指出的,最好的解决方案是修补现有框架以使其成为线程安全的。但是对于更直接的需求,考虑将非线程安全版本包装在线程安全外观中:
public class ThreadSafeBloomFilter {
private BloomFilter filter;
public ThreadSafeBloomFilter(BloomFilter filter) {
this.filter = filter;
}
public synchronized void add(Object obj) {
filter.add(obj);
}
}
以类似的方式实现您需要的其他方法。您可能还想让它变得漂亮和通用(例如 ThreadSafeBloomFilter,但这是您的决定)。
在性能方面,这将序列化所有请求,因此您不会通过并行访问它来体验任何性能提升(并且可能会造成瓶颈)。
我上周遇到了这个问题。
最终为番石榴布隆过滤器创建了一个包装类,我在其中创建了许多过滤器。然后根据要插入的键,我选择了一个过滤器并单独同步。使用 256 个过滤器和 8 个并发线程运行,即使添加了同步,我的 CPU 利用率也达到了 90%。
我采用了 Apache Cassandra 版本来支持并发更新,因为我们在内部需要这个属性。你可以在这里查看:https ://github.com/ifesdjeen/blomstre
我用不同的布隆过滤器制作了 java 库,它们都是线程安全的。看看这个。ponkin/布卢姆