Java 执行器服务不一致
我正在测试HashIds的冲突。以下是依赖关系:Java 执行器服务不一致,java,multithreading,Java,Multithreading,我正在测试HashIds的冲突。以下是依赖关系: <!-- https://mvnrepository.com/artifact/org.hashids/hashids --> <dependency> <groupId>org.hashids</groupId> <artifactId>hashids</artifactId> <version>1
<!-- https://mvnrepository.com/artifact/org.hashids/hashids -->
<dependency>
<groupId>org.hashids</groupId>
<artifactId>hashids</artifactId>
<version>1.0.3</version>
</dependency>
org.hashids
哈希德
1.0.3
我正在使用以下代码:
Hashids hashids = new Hashids("xyz", 6, "0123456789ABCDEFGHJKLMNPQRSTUVWXYZ");
System.out.println("*******************************************************************");
System.out.println("Started");
Set<String> set = new HashSet();
ExecutorService executor = Executors.newFixedThreadPool(4);
AtomicLong count = new AtomicLong(0);
final long max = 10_000_000;
for (long i = 1; i <= max; i++) {
executor.execute(() -> {
set.add(hashids.encode(count.incrementAndGet()));
// This is just to show me that there is some activity going on
if (count.get() % 100_000 == 0) {
System.out.println(count.get() + ": " + new Date());
}
});
}
// Wait till the executor service tasks are done
executor.shutdown();
while (!executor.isTerminated()) {
Thread.sleep(1000);
}
// Assert that the Set did not receive duplicates
Assert.assertEquals(max, set.size());
System.out.println("Ended");
System.out.println("*******************************************************************");
Hashids Hashids=新的Hashids(“xyz”,6,“0123456789ABCDEFGHJKLMNPQRSTUVWXYZ”);
System.out.println(“*******************************************************************************************************************”);
System.out.println(“已启动”);
Set=newhashset();
ExecutorService executor=Executors.newFixedThreadPool(4);
AtomicLong计数=新的AtomicLong(0);
最终最大长度=10_000_000;
对于(长i=1;i{
set.add(hashids.encode(count.incrementAndGet());
//这只是为了告诉我,有一些活动正在进行
if(count.get()%100_000==0){
System.out.println(count.get()+“:“+新日期());
}
});
}
//等待执行器服务任务完成
executor.shutdown();
而(!executor.isTerminated()){
睡眠(1000);
}
//断言集合未接收到重复项
Assert.assertEquals(max,set.size());
系统输出打印项次(“结束”);
System.out.println(“*******************************************************************************************************************”);
因此,我放置了一个ExecutorService
,以使它更快一点,但我遇到了问题。或者
ExecutorService
未完成,它挂起在那里集合
包含重复的值,因此断言失败for
循环比使用ExecutorService
executor.shutdown()之后立即调用代码>
集合
不是线程安全的,请尝试使用集合包装您的集合。synchronizedSet(Set)
,或基于ConcurrentHashMap.newKeySet()
创建集合,请参阅此讨论将大量相对快速的任务排队可能会带来很大的开销。取而代之的是,您只能对4个任务进行排队,它们在整数的分区上循环。这将更快,因为队列开销和可能的代码位置(缓存)减少了。此外,它还避免了对计数器和集合的并发访问。
ConcurrentHashMap.newKeySet()
更易于使用该同步集
,因为您不需要手动处理同步。我忘记了集合。同步集(set)
。现在已经奏效了。尽管点编号3
仍处于挂起状态。如果没有ExecutorService
,与使用ExecutorService
相比所需的时间更少。是的,ConcurrentHashMap.newKeySet()
可能比synchronizedSet
具有更好的并发性能,我将更新答案。@Kihats第3点可能是创建不同线程的开销,启动和加入它们比您从集合中获得的时间增益要大。synchronizedSet(set)只需添加同步块,因此它可能会增加set.add()上的时间。另一种评测方法是,您可以尝试使用另一个AtomicLong
变量对花费在hashids.encode()
上的时间求和。