Bloom Filter(布隆过滤器)
----------------------------------------------------------------------------------------------------
Java 作为一门强类型、面向对象的编程语言,应用场景覆盖后端开发、大数据、安卓开发等多个领域。结合你之前关注的「布隆过滤器及替代工具」,以下从 核心知识点、高频应用场景、进阶优化 三个维度,整理 Java 开发中最实用的内容,同时聚焦你之前关心的「高效数据结构 / 工具」方向:
一、Java 核心基础(高效数据结构相关)
1. 集合框架:布隆过滤器之外的高效选择
Java 原生集合是「无假阳性」存在性判断的基础,需掌握其特性以适配不同场景:
| 集合类 | 核心特性 | 适用场景 |
|---|---|---|
HashSet |
O (1) 查询 / 插入,无假阳性,非线程安全 | 单机、小数据量(万级)存在性判断 |
ConcurrentHashMap |
分段锁、线程安全,O (1) 查询 | 高并发下的键值存储 / 存在性判断 |
EnumSet |
基于位向量实现,内存占用极低 | 枚举类型的存在性判断(如状态校验) |
LinkedHashSet |
有序 HashSet,维护插入顺序 | 需有序的去重 / 存在性判断 |
示例:高并发存在性判断
java
运行
import java.util.concurrent.ConcurrentHashMap;
// 并发安全的存在性判断(无假阳性)
public class ConcurrentExistCheck {
private static final ConcurrentHashMap<Long, Boolean> VALID_IDS = new ConcurrentHashMap<>();
static {
// 预加载有效 ID
VALID_IDS.put(1001L, true);
VALID_IDS.put(1002L, true);
}
// 高并发下判断 ID 是否存在
public static boolean isIdValid(Long id) {
return VALID_IDS.containsKey(id);
}
public static void main(String[] args) {
System.out.println(isIdValid(1001L)); // true
System.out.println(isIdValid(9999L)); // false
}
}
2. 并发编程:高效数据结构的线程安全保障
布隆过滤器 / 集合类在高并发场景下需保证线程安全,Java 提供以下核心工具:
- 锁机制:
ReentrantLock(可重入锁)、ReadWriteLock(读写锁,适合多读少写); - 原子类:
AtomicLong、AtomicReference、AtomicLongMap(Guava,高并发计数); - 并发容器:
CopyOnWriteArrayList(读多写少)、BlockingQueue(生产消费)。
示例:Guava AtomicLongMap 高并发计数去重
java
运行
import com.google.common.util.concurrent.AtomicLongMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class HighConcurrencyCount {
private static final AtomicLongMap<String> USER_COUNT = AtomicLongMap.create();
private static final int THREAD_POOL_SIZE = 10;
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
// 模拟 1000 次并发计数
for (int i = 0; i < 1000; i++) {
executor.submit(() -> {
USER_COUNT.incrementAndGet("user:1001");
});
}
executor.shutdown();
// 输出最终计数(应为 1000)
System.out.println(USER_COUNT.get("user:1001"));
}
}
二、Java 高频应用场景(结合布隆过滤器 / 高效工具)
1. 缓存穿透防护(最核心场景)
结合 Caffeine + Redis + 布隆过滤器,打造「多级防护」的缓存体系:
java
运行
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.springframework.data.redis.core.StringRedisTemplate;
import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;
@Service
public class MultiLevelCacheService {
@Resource
private RedissonClient redissonClient;
@Resource
private StringRedisTemplate redisTemplate;
@Resource
private ProductMapper productMapper;
// 1. 本地布隆过滤器(Caffeine 内置)
private final LoadingCache<Long, ProductDTO> localCache = Caffeine.newBuilder()
.maximumSize(10_000)
.expireAfterWrite(5, TimeUnit.MINUTES)
.bloomFilter(100_000L, 0.001) // 本地布隆过滤器参数
.build(this::loadProductFromRedis);
// 2. 分布式布隆过滤器(Redis)
private RBloomFilter<Long> distributedBloomFilter() {
RBloomFilter<Long> bf = redissonClient.getBloomFilter("product_bf");
bf.tryInit(1_000_000L, 0.01); // 100 万元素,1% 假阳性率
return bf;
}
// 查询商品(本地缓存 → 分布式布隆过滤器 → Redis → 数据库)
public ProductDTO getProduct(Long productId) {
// 第一步:查本地缓存(最快)
ProductDTO localProduct = localCache.getIfPresent(productId);
if (localProduct != null) {
return localProduct;
}
// 第二步:分布式布隆过滤器判断是否存在
if (!distributedBloomFilter().contains(productId)) {
return null;
}
// 第三步:查 Redis
String redisKey = "product:" + productId;
String redisValue = redisTemplate.opsForValue().get(redisKey);
if (redisValue != null) {
ProductDTO product = JSON.parseObject(redisValue, ProductDTO.class);
localCache.put(productId, product)
