Java 多线程代码太慢,工作人员太多,但速度太快,工作人员太少

Java 多线程代码太慢,工作人员太多,但速度太快,工作人员太少,java,multithreading,performance,concurrency,brute-force,Java,Multithreading,Performance,Concurrency,Brute Force,我写了一个代码来加速蛮力算法,我决定使用多线程。虽然我是多线程新手,而且我知道通过创建大量工作线程并将作业分配给它们,蛮力应该非常快。我下面的代码在工作人员较少(10人或更少)的情况下工作得更快,但在工作人员较多(1000人)的情况下工作得更慢。为什么会有这种奇怪的行为?错误在哪里 ExecutorService executor = Executors.newFixedThreadPool(1000); List<Callable<Integer>&g

我写了一个代码来加速蛮力算法,我决定使用多线程。虽然我是多线程新手,而且我知道通过创建大量工作线程并将作业分配给它们,蛮力应该非常快。我下面的代码在工作人员较少(10人或更少)的情况下工作得更快,但在工作人员较多(1000人)的情况下工作得更慢。为什么会有这种奇怪的行为?错误在哪里

ExecutorService executor = Executors.newFixedThreadPool(1000);
            List<Callable<Integer>> callList = new ArrayList<>();
            Callable<Integer> worker;
            for (int i = 0; i < 1000; i++) {
                worker = new WorkerThread(start, end, id);
                Thread.currentThread().setName("Staff  "+i);
                callList.add(worker);
                start = end;
                end = end + addition + 1;
            }
            int result = executor.invokeAny(callList);
            System.out.println("Done Work");

            System.out.println(result);
            executor.shutdownNow();
            executor.awaitTermination(5, TimeUnit.NANOSECONDS);
ExecutorService executor=Executors.newFixedThreadPool(1000);
List callList=new ArrayList();
可呼叫工人;
对于(int i=0;i<1000;i++){
worker=新WorkerThread(开始、结束、id);
Thread.currentThread().setName(“Staff”+i);
callList.add(worker);
开始=结束;
结束=结束+添加+1;
}
int result=executor.invokeAny(调用列表);
System.out.println(“完成的工作”);
系统输出打印项次(结果);
执行者。关机现在();
执行器等待终止(5,时间单位纳秒);

要详细说明Slaw的评论,当您并行运行一个进程时,处理器实际上可以并行执行的数量是有限的。当使用的线程数小于或等于计算机的线程数时,处理器理论上可以同时运行代码(如果没有其他任务)。然而,除此之外,处理器必须开始在线程之间来回切换,使程序看起来好像是并行运行的(实际上,它是按顺序运行的)。在进程之间切换需要时间(并且会减慢程序)

欲了解更多信息,请阅读: 调度员和调度员


为了详细说明Slaw的评论,当您并行运行一个进程时,处理器实际上可以并行执行的数量是有限的。当使用的线程数小于或等于计算机的线程数时,处理器理论上可以同时运行代码(如果没有其他任务)。然而,除此之外,处理器必须开始在线程之间来回切换,使程序看起来好像是并行运行的(实际上,它是按顺序运行的)。在进程之间切换需要时间(并且会减慢程序)

欲了解更多信息,请阅读: 调度员和调度员


任务调度器和访问数据的线程中可能存在大量开销。你可能需要和逻辑CPU核一样多的工人。并行性水平受计算机硬件的限制。例如,如果您只有8个处理器,那么一次只能运行8个线程(跨所有进程)。线程数超过可用处理器数会带来开销,特别是当任务受CPU限制时。@Slaw我使用的mac只有2个内核和1个处理器(Intel Core i5 2.4 GHz)。这意味着我一次只能运行一个线程?可能我使用了错误的术语。如果您的计算机有两个内核,那么它应该能够并行运行至少两个线程。例如,在我的Windows10机器上,我有四个内核,但有八个逻辑处理器,我相信这意味着我可以并行运行八个线程。不,两个内核意味着两个线程可以并行执行。当他们需要做一些不需要CPU(通常是IO)的事情时,拥有更多的CPU会更好。通常,使用2*numberOfCores线程<代码>++++关于超线程,Slaw是正确的,虚拟核(逻辑处理器)计数,因此它们确实可以并行运行8个线程。在某些情况下,不使用所有虚拟内核会更好,但这种情况很少见。任务调度器和访问数据的线程中可能存在大量开销。你可能需要和逻辑CPU核一样多的工人。并行性水平受计算机硬件的限制。例如,如果您只有8个处理器,那么一次只能运行8个线程(跨所有进程)。线程数超过可用处理器数会带来开销,特别是当任务受CPU限制时。@Slaw我使用的mac只有2个内核和1个处理器(Intel Core i5 2.4 GHz)。这意味着我一次只能运行一个线程?可能我使用了错误的术语。如果您的计算机有两个内核,那么它应该能够并行运行至少两个线程。例如,在我的Windows10机器上,我有四个内核,但有八个逻辑处理器,我相信这意味着我可以并行运行八个线程。不,两个内核意味着两个线程可以并行执行。当他们需要做一些不需要CPU(通常是IO)的事情时,拥有更多的CPU会更好。通常,使用2*numberOfCores线程<代码>++++关于超线程,Slaw是正确的,虚拟核(逻辑处理器)计数,因此它们确实可以并行运行8个线程。有些情况下,不使用所有虚拟核更好,但这种情况很少见。