Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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,实际上,我编写了一个Java程序来计算斐波那契数列上的一个特定数字 现在的问题是,我使用的核心数作为所需的线程数。但是我观察到,随着输入大小的增加,我通过增加线程的数量来获得更好的性能 关于如何将问题划分为多个线程,是否存在现有的公式/理论 以下是源代码: import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.

实际上,我编写了一个Java程序来计算斐波那契数列上的一个特定数字

现在的问题是,我使用的核心数作为所需的线程数。但是我观察到,随着输入大小的增加,我通过增加线程的数量来获得更好的性能

关于如何将问题划分为多个线程,是否存在现有的公式/理论

以下是源代码:

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class Fibonacci {
    private static long[] value;

    public static void main(String args[]) throws InterruptedException {
        int n;
        try {
            n = Integer.parseInt(args[0]);
        } catch (Exception e) {
            throw new RuntimeException(
                    "Please enter in the form java n number ");
        }
        value = new long[n + 1];


        long start = System.nanoTime();
        int nThreads = Runtime.getRuntime().availableProcessors();
        ExecutorService executorService = Executors
                .newFixedThreadPool(nThreads);
        int result;
        try {
            result = fibonacciSum(n, executorService);
        } catch (ExecutionException e) {
            throw new RuntimeException("Thread Interuppted ");
        }
        System.out.print(" MultiThreading = " + result);
        long end = System.nanoTime();
        System.out.println("\t time = " + (end - start) + "ns");
    }


    private static class FibonacciThread implements Runnable {
        int index;
        int result;
        ExecutorService executorService;

        public FibonacciThread(int index) {
            this.index = index;
        }

        public void run() {
            try {
                this.result = fibonacciSum(index, executorService);
            } catch (Exception e) {
                throw new RuntimeException("Thread interupted");
            }
        }
    }

    private static int fibonacciSum(int index, ExecutorService executorService)
            throws InterruptedException, ExecutionException {
        if (index <= 2) {
            return 1;
        } else {

            FibonacciThread fibonacciThread1 = new FibonacciThread(index - 2);
            fibonacciThread1.executorService = executorService;
            Future future = executorService.submit(fibonacciThread1);
            Object object = future.get();
            int resultPart2 = fibonacciSum(index - 1, executorService);
            int result = fibonacciThread1.result + resultPart2;
            // executorService.shutdown();
            return result;
        }
    }

}
import java.util.concurrent.ExecutionException;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
导入java.util.concurrent.Future;
公共类斐波那契{
私有静态长[]值;
公共静态void main(字符串args[])引发InterruptedException{
int n;
试一试{
n=整数.parseInt(args[0]);
}捕获(例外e){
抛出新的运行时异常(
“请在表格中输入java n编号”);
}
值=新长[n+1];
长启动=System.nanoTime();
int nThreads=Runtime.getRuntime().availableProcessors();
ExecutorService ExecutorService=执行者
.newFixedThreadPool(n个线程);
int结果;
试一试{
结果=fibonacciSum(n,服务);
}捕获(执行例外){
抛出新的RuntimeException(“线程中断”);
}
System.out.print(“多线程=”+结果);
long end=System.nanoTime();
System.out.println(“\t time=“+(结束-开始)+”ns”);
}
私有静态类FibonacciThread实现Runnable{
整数指数;
int结果;
执行服务执行服务;
公共FibonacciThread(int索引){
这个指数=指数;
}
公开募捐{
试一试{
this.result=fibonacciSum(索引、服务);
}捕获(例外e){
抛出新的运行时异常(“线程中断”);
}
}
}
私有静态int-fibonacciSum(int索引,ExecutorService-ExecutorService)
抛出InterruptedException、ExecutionException{

如果(index没有公式,因为它取决于您的问题、您的操作系统等。您将达到上下文切换的开销对您的原因没有帮助的程度。如果每个任务都是相同的,那么同一进程上的更多线程将意味着上下文切换


最好在这里试验一下如何达到最佳状态。

我认为对于要创建的线程数量没有现成的公式。您必须考虑I/O等因素。如果您的线程在I/O调用上被阻塞(速度要慢得多)另一方面,如果您的线程计算量大,并且不需要I/O,那么将线程数与内核数匹配是一个好主意,因为这样可以避免线程之间切换的开销。

如果您还没有意识到这一点,那么斐波那契数就不是了并行化的一个很好的候选者。您将获得(越来越)更好的性能:

  • 通过使用单线程递归算法
  • 通过使用带记忆的单线程递归算法,以及
  • 通过求解递推关系并实现得到的公式

基本问题是,朴素的斐波那契计算需要指数级的计算步骤。多线程无法影响这一点(在性能方面),因为处理器数量有限

即使处理器的数量是无限的,线程设置/任务创建的开销也超过了执行计算步骤所需的时间

最后,使用executor服务和有界线程池进行Fibonacci有一个特殊的问题。如果线程池太小(或N太大),计算很容易陷入停滞。例如,您编码的方式需要池中的
~N
线程来计算
Fibonacci(N)
,即使大多数线程在大多数时间都会被阻塞。(理解这一点的最佳方法是“手动执行”应用程序,注意每个时间点有多少线程在使用……以及它们在做什么。)


因此,您的问题的简单答案是(对于这个特定的应用程序),您需要池中至少
N
个线程来完成
Fibonacci(N)
的计算(这不是一个一般性的答案。这是由您实现的算法的细节决定的)



在使用Fibonacci数来计算线程时,还有很多其他问题和答案。我建议你也阅读它们。

< P>一个重要的考虑线程最佳数量的因素是问题的并行度。对于一个只能一次执行4个任务的问题,没有一个点有多个。4个线程(甚至可能更慢)

如你所知,斐波那契级数的公式是

f(1) = 1
f(2) = 1
f(n) = f(n-1) + f(n-2)
唯一的平行度适用于小于3的值。对于大于此值的数字,在上一个值出现之前,无法计算每个值。这意味着最佳线程数为1,且仅为1

你可能会说,为什么会有更多的线程出现以提高性能。这可能是因为你采取了一种低效的策略,而这正是你正在加速的低效


如果您从一开始就采取最有效的策略,那么最佳线程数是一个。

拼写“number”会让您丧命吗?另外,第n个Fibonnacci数有一个封闭形式的表达式,也许你会对此感兴趣。我只需要加倍可用的
处理器
,这将提供大量线程,而开销很小。@Daniel-这是一个很好的一般规则