Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 执行器服务不一致_Java_Multithreading - Fatal编程技术网

Java 执行器服务不一致

Java 执行器服务不一致,java,multithreading,Java,Multithreading,我正在测试HashIds的冲突。以下是依赖关系: <!-- https://mvnrepository.com/artifact/org.hashids/hashids --> <dependency> <groupId>org.hashids</groupId> <artifactId>hashids</artifactId> <version>1

我正在测试HashIds的冲突。以下是依赖关系:

    <!-- 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()
    上的时间求和。