`

对java的BitSet的多线程并发的探索

 
阅读更多
java的BitSet不是线程安全的,所以多线程的时候h要加锁。
1 直接加锁整个BitSet        用时:3.4秒 
2 BitSet拆成更小的粒度     用时:3.6秒
3 使用并发的BitSet,自己写了个AtomicBitSet   用时:3.3秒

从测试结果来看 性能都差不多
感觉有点疑惑,在我的想象中2还和3应该会比1好不少的啊

下面3个测试分别对应3种方式
附件是完整代码


测试1
package com.eyu.gift.service;

import java.util.BitSet;
import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

import org.junit.Test;

/**
 * 用时3.4秒
 * @author bean
 */
public class BitsetTest1 {
	public static final int NUM = 50000000;

	@Test
	public void mutiThreadTest() {
		BitSet bitset = new BitSet();
		ThreadPoolExecutor executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(20);
		int total = NUM / 10;
		Random random = new Random(1234);
		for (int i = 1; i < total; i++) {
			int targrt = random.nextInt(NUM);
			if (targrt % 5 == 0) {
				executorService.execute(new Task1(bitset, i));
			} else {
				executorService.execute(new ReadBitTask1(bitset, i));
			}
		}
		executorService.shutdown();
		while (true) {
			if (executorService.isTerminated()) {
				break;
			}
		}
	}

}

class Task1 implements Runnable {
	private int id;
	private BitSet bitset;

	public Task1(BitSet bitset, int id) {
		this.bitset = bitset;
		this.id = id;
	}

	@Override
	public void run() {
		synchronized (bitset) {
			bitset.set(id);
		}

	}
}

class ReadBitTask1 implements Runnable {
	private int id;
	private BitSet bitset;

	public ReadBitTask1(BitSet bitset, int id) {
		this.bitset = bitset;
		this.id = id;
	}

	@Override
	public void run() {
		synchronized (bitset) {
			bitset.get(id);
		}

	}
}



测试2
package com.eyu.gift.service;

import java.util.BitSet;
import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

import org.junit.Test;

/**
 * 用时3.6秒
 * @author bean
 */
public class BitsetTest2 {
	public static final int NUM = 50000000;
	static Object[] locks;

	static {
		locks = new Object[10000];
		for (int i = 0; i < 10000; i++) {
			locks[i] = new Object();
		}
	}

	@Test
	public void mutiThreadTest() {
		BitSet bitset = new BitSet();
		ThreadPoolExecutor executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(20);
		int total = NUM / 10;
		Random random = new Random(1234);
		for (int i = 1; i < total; i++) {
			int targrt = random.nextInt(NUM);
			if (targrt % 5 == 0) {
				executorService.execute(new Task2(bitset, i));
			} else {
				executorService.execute(new ReadTask2(bitset, i));
			}
		}
		executorService.shutdown();
		while (true) {
			if (executorService.isTerminated()) {
				break;
			}
		}
	}

	public static Object getLock(int i) {
		return locks[i % 10000];
	}

}

class Task2 implements Runnable {
	private int id;
	private BitSet bitset;

	public Task2(BitSet bitset, int id) {
		this.bitset = bitset;
		this.id = id;
	}

	@Override
	public void run() {
		Object lockObject = BitsetTest2.getLock(id);
		synchronized (lockObject) {
			bitset.set(id);
		}

	}
}

class ReadTask2 implements Runnable {
	private int id;
	private BitSet bitset;

	public ReadTask2(BitSet bitset, int id) {
		this.bitset = bitset;
		this.id = id;
	}

	@Override
	public void run() {
		Object lockObject = BitsetTest2.getLock(id);
		synchronized (lockObject) {
			bitset.get(id);
		}

	}
}



测试3

package com.eyu.gift.service;

import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

import org.junit.Test;

/**
 * 用时3.3秒
 * @author bean
 */
public class BitSetTest3 {

	public static final int NUM = 50000000;

	@Test
	public void mutiAtomThreadTest() {
		AtomicBitSet bitset = new AtomicBitSet(NUM);
		ThreadPoolExecutor executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(20);
		int total = NUM / 10;
		Random random = new Random(1234);
		for (int i = 1; i < total; i++) {
			int targrt = random.nextInt(NUM);
			if (targrt % 5 == 0) {
				executorService.execute(new Task3(bitset, i));
			} else {
				executorService.execute(new ReadTask3(bitset, i));
			}
		}
		executorService.shutdown();
		while (true) {
			if (executorService.isTerminated()) {
				break;
			}
		}
	}

}

class Task3 implements Runnable {
	private int id;
	private AtomicBitSet bitset;

	public Task3(AtomicBitSet bitset, int id) {
		this.bitset = bitset;
		this.id = id;
	}

	@Override
	public void run() {
		bitset.set(id);

	}
}

class ReadTask3 implements Runnable {
	private int id;
	private AtomicBitSet bitset;

	public ReadTask3(AtomicBitSet bitset, int id) {
		this.bitset = bitset;
		this.id = id;
	}

	@Override
	public void run() {
		bitset.get(id);

	}
}



并发安全BitSet:
package com.eyu.gift.service;

import java.util.concurrent.atomic.AtomicIntegerArray;

public class AtomicBitSet {
    private final AtomicIntegerArray array;

    public AtomicBitSet(int length) {
        int intLength = (length + 31) / 32;
        array = new AtomicIntegerArray(intLength);
    }

    public void set(long n) {
        int bit = 1 << n;
        int idx = (int) (n >>> 5);
        while (true) {
            int num = array.get(idx);
            int num2 = num | bit;
            if (num == num2 || array.compareAndSet(idx, num, num2))
                return;
        }
    }

    public boolean get(long n) {
        int bit = 1 << n;
        int idx = (int) (n >>> 5);
        int num = array.get(idx);
        return (num & bit) != 0;
    }
}





0
0
分享到:
评论

相关推荐

    java bitset 源码解析.rtf

    java bitset 高级数据结构 源码解析 适合 0-3 年开发人员,进阶、面试必备知识!

    javabitset源码-javaewah:JavaBitSet类的压缩替代品

    bitset源码Java 这是 Java Bitset 类的字对齐压缩变体。 我们提供 64 位和 32 位类似 RLE 的压缩方案。 它可用于实现位图索引。 它所依赖的 EWAH 格式用于运行 GitHub 的 git 实现。 字对齐压缩的目标不是实现最佳...

    javabitset源码-JerrySoundCode:杰瑞声码

    bitset源码Java源码分析 基础集合列表 ArrayList (done) Vector (done) LinkedList (done) Stack (done) ReferenceQueue (done) ArrayDeque (done) Set HashSet (done) TreeSet (done) LinkedHashSet (done) BitSet ...

    浅谈Java BitSet使用场景和代码示例

    主要介绍了浅谈Java BitSet使用场景和代码示例,具有一定借鉴价值,需要的朋友可以参考下。

    javabitset源码-java_master:后端架构师技术图谱

    java bitset 源码 最后更新于20180424 (Toc generated by ) 数据结构 队列 非阻塞队列:ConcurrentLinkedQueue(无界线程安全),采用CAS机制(compareAndSwapObject原子操作)。 阻塞队列:ArrayBlockingQueue(有界...

    javabitset源码-Java8-learning:学习Java8新特性

    Java8的函数式编程能够大大减少代码量和便于维护,同时,还有一些跟并发相关的功能。开发中常用到的新特性如下: 1. 接口的默认方法和静态方法 在Java8之前,接口中只能包含抽象方法。那么这有什么样弊端呢?比如,...

    bitset用法 bitset用法

    bitset用法bitset用法bitset用法bitset用法bitset用法bitset用法

    BitSet 源码分析.txt

    基于JDK1.8的BitSet 源码分析, 描述了实现的原理 个方法的含义 虽然没有写出实际的测试代码 但是只要是细度了我的这个分析 在使用的时候就不是问题了

    java 原生包 BitSet 源码

    Java 原生包 BitSet 源码,0~3年 Java 工程师必看,属于高级数据结构,利于进阶,面试必备!

    javabitset源码-myleetcode:所有LeetCode问题的记录

    java bitset源码 目前进度(171/237) LeetCode做题笔记 Add two numbers:给定一个数集合和一个数,已知集合中有两个数的和是给定数,求这两个加数的index 方法1:暴力,n^2时间复杂度,不推荐 方法2:快速排序nlogn...

    javabitset源码-Study:学习

    多线程 线程安全 一致性、事务 事务 ACID 特性 事务的隔离级别 MVCC 锁 Java中的锁和同步类 公平锁 & 非公平锁 悲观锁 乐观锁 & CAS ABA 问题 CopyOnWrite容器 RingBuffer 可重入锁 & 不可重入锁 互斥锁 & 共享锁 ...

    C语言头文件 BITSET

    C语言头文件 BITSETC语言头文件 BITSETC语言头文件 BITSETC语言头文件 BITSETC语言头文件 BITSETC语言头文件 BITSETC语言头文件 BITSETC语言头文件 BITSETC语言头文件 BITSETC语言头文件 BITSETC语言头文件 BITSETC...

    动态Bitset源代码

    在C++的STL中实现由一个bitset类模板,其用法如下: std::bitset&lt;64&gt; bs; 也就是说,这个bs只能支持64位以内的位存储和操作;bs一旦定义就不能动态增长了。本资源附件中实现了一个动态Bitset,和标准bitset兼容。 /*...

    java基础之BitSet - 副本.md

    java基础之BitSet - 副本

    javabitset源码-my-jvm-demos:Java/Kotlin演示

    bitset源码 这个仓库主要放一些 Demo 示例 目录 1. Kotlin 实现 IGetInt java 接口的方法示例: public class IGetInt { String get(int i); String get(Integer i); } 2. Java 并发示例 此部分Demo基本用于实现 《》...

    javabitset源码-montysolr:Solr天体物理数据系统

    java bitset 源码

    javabitset源码-all-kinds-book:java大数据sparkflinkredishivehbasekafka面试题数据结构

    bitset 源码 all-kinds-book 主要包含 java 大数据 数据仓库 数据分析 第三方组件 面试题 数据结构与算法 设计模式 软件设计 等文档 ,可以访问我们的官网查看更多内容 [人在地上跑 牛在天上飞](#人在地上跑 牛在...

    RoaringBitmap, 在Java中,一个更好的压缩 bitset.zip

    RoaringBitmap, 在Java中,一个更好的压缩 bitset RoaringBitmap Bitsets,也称为位图,通常用作快速数据结构。 不幸的是,他们可以使用太多的内存。 为了补偿,我们经常使用压缩位图。咆哮位图是压缩位图,它比传统...

    javabitset源码-redis-bloomfilter:基于Redis的BloomfilterforJava

    java bitset 源码 redis-bloomFilter redis-bloomFilter是基于redis的bitset实现的bloomfilter.具体原理和实现思路可以参考 使用 redis-bloomFilter发布在JitPack,可以选择下载源码编译,或者通过jitpack源添加依赖...

Global site tag (gtag.js) - Google Analytics