int类型数值分配类, 不是线程安全的
1、成员变量
| 变量名 | 默认值 | 描述 |
|---|---|---|
| final int loRange | ||
| final int hiRange | ||
| final int numberOfBits | hiRange-logRange (数字个数) | |
| int lastIndex | 0 | 搜索free的数字 |
| final BitSet freeSet | 表示某个数字是否被分配了 |
2、方法
| 方法名称 | 描述 | 图示 |
|---|---|---|
| IntAllocator(int bottom, int top) | 构造方法,这个范围都是包含的,创建freeSet对象,将每个位置都设置为0 | |
| int allocate() | 分配可一个可用数字 | |
| void free(int reservation) | 释放某个数字 | |
| boolean reserve(int reservation) | 预定某个数字 |
2.1、总结
- 本质也就是利用BitSet特性,通道数是固定的,用完就没了,有没有类似令牌味道,可以用来限流否?
3、Test示例代码
-
public class IntAllocatorTests { private static final int TEST_ITERATIONS = 50000; private static final int HI_RANGE = 100000; private static final int LO_RANGE = 100; private final IntAllocator iAll = new IntAllocator(LO_RANGE, HI_RANGE); private final Random rand = new Random(70608L); /** * 随机生成序号,保存这个值,如果重复了就删除 * @throws Exception */ @Test public void reserveAndFree() throws Exception { Set<Integer> set = new HashSet<Integer>(); for (int i = 0; i < TEST_ITERATIONS; ++i) { // 随机生成一个数字 int trial = getTrial(rand); if (set.contains(trial)) { // 重复就是释放当前数字所在占位置 iAll.free(trial); set.remove(trial); } else { //将当前这个数字添加到IntAllocator,也就是BitSet中 assertTrue("Did not reserve free integer " + trial, iAll.reserve(trial)); set.add(trial); } } for (int trial : set) { // 已经占用不能重复插入新数字 assertFalse("Integer " + trial + " not allocated!", iAll.reserve(trial)); } } /** * 随机占用位置,不用指定 * @throws Exception */ @Test public void allocateAndFree() throws Exception { Set<Integer> set = new HashSet<Integer>(); for (int i=0; i < TEST_ITERATIONS; ++i) { if (getBool(rand)) { int trial = iAll.allocate(); assertFalse("Already allocated " + trial, set.contains(trial)); set.add(trial); } else { if (!set.isEmpty()) { int trial = extractOne(set); assertFalse("Allocator agreed to reserve " + trial, iAll.reserve(trial)); iAll.free(trial); } } } for (int trial : set) { assertFalse("Integer " + trial + " should be allocated!", iAll.reserve(trial)); } } /** * toString方法测试, * @throws Exception */ @Test public void testToString() throws Exception { IntAllocator ibs = new IntAllocator(LO_RANGE, HI_RANGE); assertEquals("IntAllocator{allocated = []}", ibs.toString()); ibs.allocate(); assertEquals("IntAllocator{allocated = [100]}", ibs.toString()); for(int i = 200; i<211; i=i+4) { ibs.reserve(i); ibs.reserve(i+1); ibs.reserve(i+2); } assertEquals("IntAllocator{allocated = [100, 200..202, 204..206, 208..210]}" , ibs.toString()); } private static int extractOne(Set<Integer> set) { Iterator<Integer> iter = set.iterator(); int trial = iter.next(); iter.remove(); return trial; } // 生成随机数字, 范围为LO_RANGE 到 HI_RANGE private static int getTrial(Random rand) { return rand.nextInt(HI_RANGE-LO_RANGE+1) + LO_RANGE; } // 随机生成boolean值 private static boolean getBool(Random rand) { return rand.nextBoolean(); } }
3、总结
- 利用BitSet来确定某个数字是否已经使用过了
- 这个可以利用BitSet来限流或者说令牌
本文介绍了一个基于BitSet实现的int类型数值分配类IntAllocator,它通过BitSet特性实现数字的分配与回收,并提供了测试案例验证其正确性。
4万+

被折叠的 条评论
为什么被折叠?



