布隆过滤器实现部分场景下的高性能

过滤器

这个是概率型数据结构,主要用于判断元素是否可能存在于集合中,存在一定的误判率。在并发场景下,保证操作的线程安全,由于其概率特性,不同线程对元素存在性的判断可能会因为误判而出现不一致的情况。例如,一个线程判断某个元素存在,而实际上该元素可能并不存在于集合中。

 

maven依赖

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>32.1.3-jre</version>
</dependency>

实现布隆过滤器

复制代码
import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;

import java.nio.charset.StandardCharsets;

public class RequestProcessor {
    // 预计插入的元素数量
    private static final int EXPECTED_INSERTIONS = 10000;
    // 期望的误判率
    private static final double FALSE_POSITIVE_PROBABILITY = 0.01;

    // 创建布隆过滤器
    private static final BloomFilter<CharSequence> processedRequestIds = BloomFilter.create(
            Funnels.stringFunnel(StandardCharsets.UTF_8),
            EXPECTED_INSERTIONS,
            FALSE_POSITIVE_PROBABILITY
    );

    public static boolean isRequestProcessed(String requestId) {
        // 判断请求 ID 是否已经存在于布隆过滤器中
        if (processedRequestIds.mightContain(requestId)) {
            // 这里存在一定的误判率,可能需要结合其他方式进一步确认
            return true;
        }
        // 如果不存在,则将请求 ID 添加到布隆过滤器中
        processedRequestIds.put(requestId);
        return false;
    }

    public static void main(String[] args) {
        String requestId1 = "12345";
        String requestId2 = "67890";

        // 处理第一个请求
        boolean isProcessed1 = isRequestProcessed(requestId1);
        System.out.println("Request ID 1 processed: " + isProcessed1);

        // 再次处理第一个请求
        boolean isProcessed2 = isRequestProcessed(requestId1);
        System.out.println("Request ID 1 processed again: " + isProcessed2);

        // 处理第二个请求
        boolean isProcessed3 = isRequestProcessed(requestId2);
        System.out.println("Request ID 2 processed: " + isProcessed3);
    }
}
复制代码

测试并发安全

复制代码
import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class BloomFilterConcurrentExample {
    private static final int EXPECTED_INSERTIONS = 10000;
    private static final double FALSE_POSITIVE_PROBABILITY = 0.01;
    private static final BloomFilter<CharSequence> processedRequestIds = BloomFilter.create(
            Funnels.stringFunnel(StandardCharsets.UTF_8),
            EXPECTED_INSERTIONS,
            FALSE_POSITIVE_PROBABILITY
    );

    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(10);
        for (int i = 0; i < 100; i++) {
            final int id = i;
            executor.submit(() -> {
                String requestId = String.valueOf(id);
                if (processedRequestIds.mightContain(requestId)) {
                    System.out.println("Request ID " + requestId + " might be processed.");
                } else {
                    processedRequestIds.put(requestId);
                    System.out.println("Request ID " + requestId + " is marked as processed.");
                }
            });
        }
        executor.shutdown();
    }
}
复制代码

 

posted @   白玉神驹  阅读(24)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示