`

对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
分享到:
评论

相关推荐

    javabitset源码-Study:学习

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

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

    3. **并发支持**:Java中的BitSet是线程安全的,这使得它在多线程环境中处理并行查询和更新成为可能。 4. **位数组操作**:通过BitSet提供的API,可以方便地检查、设置、清除和翻转位,这对于构建复杂的查询逻辑...

    java敏感词检索工具

    5. **多线程处理**:当需要处理大量文本时,可以利用Java的多线程技术,将文本分割成多个部分,分别在不同线程中进行敏感词检索,从而提升整体处理速度。 6. **缓存策略**:考虑到敏感词库可能经常更新,但大部分...

    (超赞)JAVA精华之--深入JAVA API

    **1.7 Java 5.0多线程编程** - **高级主题** - 如并发工具类、锁机制等。 **1.8 Java Socket编程** - **网络编程基础** - 使用 `Socket` 和 `ServerSocket` 类实现客户端和服务端通信。 **1.9 Java的内存泄漏*...

    JAVA SE学习精华集锦

    6. **Java 5.0多线程编程**:引入了枚举、注解、泛型和并发改进,如`java.util.concurrent`包中的线程池、Future、Callable等工具。 7. **Java Socket编程**:提供客户端和服务器之间的网络通信,通过Socket和...

    28个java常用的工具类源码

    3. **StringBuffer和StringBuilder**:在多线程环境下,StringBuffer线程安全,StringBuilder则在单线程中效率更高。通过源码,我们可以理解字符串连接的内部机制。 4. **Arrays和Collections**:这两个工具类提供...

    CMPP Java 源码

    学习和分析这个Java源码库,不仅可以深入了解CMPP协议的实现细节,还能提升对Java网络编程、多线程、Web开发以及数据库操作等技术的理解。对于想要从事中国移动相关业务开发的工程师来说,这是一个非常有价值的参考...

    SelectRepeat选择重传的java实现

    7. **并发与多线程**:考虑到网络通信通常涉及异步操作,使用Java的`ExecutorService`和`Future`接口可以有效地管理发送和接收线程。 8. **异常处理**:处理网络通信中的各种异常情况,如连接断开、数据包乱序等,...

    改进的Wu—Manber多模式串匹配算法(Java源码)

    4. **优化**:为了提高性能,可以考虑使用Java的并发和并行处理技术,如多线程或 Fork/Join 框架,来处理大规模的数据。 在实际应用中,关键词匹配是信息过滤、内容审查、搜索引擎优化等多个领域的重要组成部分。Wu...

    Java 项目-搜索引擎的设计与实现.zip

    5. **线程与并发**:为了提高爬取和索引的效率,项目可能采用了多线程或异步处理技术。Java的并发API如ExecutorService、Future和CompletableFuture等,可以有效地管理多个任务。 6. **用户接口**:虽然描述中未...

    java实现CMPP3.0源代码

    3. **多线程编程**:为了提高并发处理能力,通常会使用多线程来处理不同任务,如一个线程负责接收,另一个线程负责发送。Java的`Thread`类和`Runnable`接口可用于实现多线程。 4. **消息编码与解码**:CMPP协议使用...

    JBuider第七章:Java.util包.rar

    Java.util.concurrent包(虽然不是直接在Java.util下,但密切相关)包含了一系列线程安全的数据结构和并发工具,如Semaphore、ExecutorService、CountDownLatch等,极大地简化了多线程编程。 8. **枚举Set**: ...

    java-util包资料

    - **CountDownLatch/CyclicBarrier/Semaphore**: 同步工具类,用于多线程间的协作。 8. **事件监听机制**: - `EventListener`接口和`EventListenerList`,用于实现事件驱动的编程模式。 9. **实用工具类**: -...

    java学习手册

    5. **并发编程**:线程、同步机制(如synchronized关键字、wait()、notify()方法)、ExecutorService、并发集合等。 6. **反射**:允许在运行时检查类、接口、字段和方法的信息,以及动态调用方法。 7. **集合框架...

    百度历年笔试面试150题.docx

    【Java面试经验】这篇文档包含了多个技术面试题,主要涉及C语言编程、算法、操作系统、数据结构和网络等领域的知识。下面将逐一解析这些题目所涵盖的Java面试知识点。 1. **C语言实现字符串倒序**:这道题虽然不是...

    生命游戏(Java swing).zip

    这个过程可能需要使用多线程以避免阻塞UI。 5. **绘制更新**:在更新逻辑完成后,重新绘制游戏面板,显示新的细胞状态。可以使用repaint()方法触发重绘。 6. **用户交互**:提供输入方式让用户可以手动改变细胞...

    spmf.zip_Apriori in java_payk7w_zip

    - **并行处理**:对于大数据集,可以考虑使用多线程或Java的并发库来加速计算。 - **I/O操作**:读取输入文件,写入输出结果,可能需要处理文件流和数据解析。 - **优化技巧**:例如,使用Bitset来高效地存储和操作...

    Java-notes:Java语言笔记

    在并发方面,Java提供了线程池、同步机制(synchronized关键字、Lock接口)、并发集合(ConcurrentHashMap等)等工具,以支持多线程环境下的高效编程。在分布式计算方面,如RMI(远程方法调用)和JMS(Java消息服务...

Global site tag (gtag.js) - Google Analytics