用于同时检查多个数字的素数的JAVA多线程比单线程慢

use*_*223 5 java optimization performance multithreading runnable

(我无法在任何地方找到答案,很抱歉,如果这是一个已被问过的问题.)

我需要检查我的用户指定的每个数字是否为素数.因此,我强行检查每个数字是否达到该值(我在技术上希望与用户希望的一样大)是否是通过检查是否为素数的素数

p%i==0
Run Code Online (Sandbox Code Playgroud)

如果p是每个奇数3的用户输入值,则为true

显然,一旦程序开始检查非常大的数字,循环通过每个单个奇数到输入值的一半就需要一段时间.由于这个限制,我的当前状态的程序在大数字上减慢了"每秒检查数"的速度,这意味着该程序可能需要很长时间才能完成非常大的数字.

为了解决这个问题,我试图为主要检查方面实现多线程,如下所示:

int CPUs = Runtime.getRuntime().availableProcessors();
int acCPU = 0;
//...
Thread pCheckThread[] = new Thread[CPUs-1];
class pCheckRunnable implements Runnable{
    long pr;
    int xp, yp;
    pCheckRunnable(long prime){
        pr=prime;
    }
    public void run(){
        if(isPrime(pr))
            //Do stuff...
    }
}
//...
for(long i=1; i<valueEntered; i++){
    pCheckThread[acCPU] = new Thread(new pCheckRunnable(i));
    pCheckThread[acCPU].start();
    acCPU++;
    if(acCPU>=CPUs){
    for(int t=0; t<pCheckThread.length; t++){
        try {
        pCheckThread[t].join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    acCPU = 0;
    }
}
Run Code Online (Sandbox Code Playgroud)

正如您可能希望看到的那样,我们的想法是检查多个数字是否同时处于素数,每个检查在一个单独的线程中运行,最大线程数等于可用的处理器核心数.

问题是,该程序现在似乎实际上运行速度较慢.

这是我第一次尝试多线程和并行处理,我可能只是犯了一些非常愚蠢的错误,或者我的代码可能会让你们中的一些经验丰富的编码员的意见变得非常混乱,所以请随时告诉我我做过任何可能导致不稳定或腐败的严重错误.

ass*_*ias 3

最可能的原因是工作单元 ( isPrime(p)) 相当小,并且启动线程比计算本身花费更多时间。

为了提高性能,您应该将任务提交给ExecutorService,其中线程数 = 处理器数(超过该数,您的线程将争夺 CPU 资源,并且会适得其反)。然后,您只需创建几个线程并重用它们,从而节省线程创建的开销。

完成后,您应该会看到明显的改善。然后,您可以尝试对任务进行分组并一次提交多个任务,看看是否会进一步提高性能。

所以它看起来像:

ExecutorService executor = 
    Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

for(long i=1; i<valueEntered; i++){
    executor.submit(new pCheckRunnable(i));
}
executor.shutdown();
executor.awaitTermination();
Run Code Online (Sandbox Code Playgroud)