多线程随着更多内核而变慢

时间:2018-04-19 10:50:58

标签: java multithreading sieve-of-eratosthenes

我试图用多线程实现Eratosthenes prime筛子。 线程由踏板处理

function previewFile(sel) {
    var preview = document.querySelector('#inp-' + sel); // use selector
    var file = document.querySelector('#'+sel).files[0]; // use selector
    ...

它自己的筛子就像这样实施

ThreadPoolExecutor executor = 
    new ThreadPoolExecutor(
        6,   // cores
        10,  // threads
        1000,
        TimeUnit.MILLISECONDS, 
        new ArrayBlockingQueue<Runnable>(n)
    );

运行方法看起来像这样

for (int i=2; i<Math.sqrt(n); i++ ){
    if (list[i].get()) { // boolean list initialized earlier
        executor.execute(new Calc(i,n));
    }
}

现在,我不明白为什么,当public void run(){ for (int j=start*2;j<n;j=j+start){ list[j].set(false); } } 较低(其他参数保持不变)时,程序运行得更快。 (2核2.5毫秒; 7 - 3.3;等)。 我想我可能会犯一些菜鸟错误,但我不明白为什么会发生这种情况?

编辑: 完整类看起来像这样(必须为集群使用单个类,因此一切都在Main:

corePoolSize

1 个答案:

答案 0 :(得分:3)

这取决于您拥有多少核心。如果你有2个内核,并且你想在7个线程上执行,那么由于线程上下文切换会使事情变慢。这被称为阿姆达尔定律。

另外值得一提的是,执行程序构造函数的前2个参数是corePoolSize,而maximumPoolSize java doc corePoolSize表示要保留在池中的线​​程数,即使它们是{{1是池中允许的最大线程数

无论如何,主要原因是你唯一测量的是执行者关闭所需的时间。您使用false初始化数组:maximumPoolSize 然后,为线程池创建任务的唯一情况是找到真正的元素list[i]=new AtomicBoolean(false);。由于没有真正的元素,这将永远不会发生,因此不会安排/执行任务。