Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/309.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_Performance - Fatal编程技术网

针对这样的情况动态生成Java线程

针对这样的情况动态生成Java线程,java,multithreading,performance,Java,Multithreading,Performance,假设我有一个整数列表。每个int必须乘以100。要使用for循环执行此操作,我将构造如下内容: for(Integer i : numbers){ i = i*100; } 但是,假设出于性能原因,我想同时为numbers中的每个数字生成一个线程,并对每个线程执行一次乘法,将结果返回到相同的列表。做这样的事情最好的方法是什么 我的实际问题并不像ints的乘法那么简单,而是循环的每次迭代都需要花费大量的时间,因此我希望同时完成所有这些任务,以减少执行时间。如果您可以使用Java 7,那么创建

假设我有一个整数列表。每个
int
必须乘以
100
。要使用
for
循环执行此操作,我将构造如下内容:

for(Integer i : numbers){
  i = i*100;
}
但是,假设出于性能原因,我想同时为
numbers
中的每个数字生成一个线程,并对每个线程执行一次乘法,将结果返回到相同的
列表。做这样的事情最好的方法是什么


我的实际问题并不像
int
s的乘法那么简单,而是循环的每次迭代都需要花费大量的时间,因此我希望同时完成所有这些任务,以减少执行时间。

如果您可以使用Java 7,那么创建的框架正是为了解决这个问题。如果没有,那么在上有一个JSR166(fork/join提案)源代码

本质上,您将为每个步骤创建一个任务(在您的示例中,为数组中的每个索引创建一个任务),并将其提交给一个可以共享线程的服务(fork部分)。然后等待一切完成并合并结果(连接部分)


使用服务而不是启动自己的线程的原因是,在创建线程时可能会有开销,并且在某些情况下,您可能希望限制线程的数量。例如,如果您在一台四CPU的机器上,那么并发运行四个以上的线程就没有多大意义。

如果您可以使用Java 7,那么创建框架正是为了解决这个问题。如果没有,那么在上有一个JSR166(fork/join提案)源代码

本质上,您将为每个步骤创建一个任务(在您的示例中,为数组中的每个索引创建一个任务),并将其提交给一个可以共享线程的服务(fork部分)。然后等待一切完成并合并结果(连接部分)


使用服务而不是启动自己的线程的原因是,在创建线程时可能会有开销,并且在某些情况下,您可能希望限制线程的数量。例如,如果您在一台四CPU的机器上,并发运行的线程数超过四个是没有多大意义的。

为您的计算机生成一个新线程

每个数字都是数字


这不是个好主意。但是,使用大小与内核/CPU数量匹配的固定线程池可能会略微提高性能。

每个数字都是数字


这不是个好主意。但是,使用大小与内核/CPU数量匹配的固定线程池可能会略微提高性能。

如果它是节点上唯一的应用程序,则应确定哪个线程数最快完成作业(最大吞吐量)。这取决于您使用的处理器JIT可以优化代码的程度,因此没有一般的建议,只有度量


在此之后,您可以将作业分配到工作线程池中,方法是:按最大吞吐量计算的数量(如果它是节点上唯一的应用程序),那么您应该确定哪个数量的线程最快完成作业(最大吞吐量)。这取决于您使用的处理器JIT可以优化代码的程度,因此没有一般的建议,只有度量


在此之后,您可以通过
数字模最大吞吐量

将作业分配到工作线程池查看
ThreadPoolExecutor
,并为每个迭代创建一个任务。但前提是这些任务是独立的


线程池的使用允许您在每次迭代中创建一个任务,但只能同时运行多个线程,因为您希望减少线程的数量,例如减少可用的内核或硬件线程的数量。创建大量线程会适得其反,因为它们需要大量的上下文切换,这会影响性能。

查看
ThreadPoolExecutor
,并为每个迭代创建一个任务。但前提是这些任务是独立的


线程池的使用允许您在每次迭代中创建一个任务,但只能同时运行多个线程,因为您希望减少线程的数量,例如减少可用的内核或硬件线程的数量。创建大量线程会适得其反,因为它们需要大量的上下文切换,这会影响性能。

我假设您是在一台普通PC上。您的机器上最多有N个线程同时执行,其中N是CPU的#个内核,因此最有可能在[1,4]范围内。加上共享列表上的争用


但更重要的是,产生一个新线程的成本远远大于进行乘法运算的成本。可以有一个线程池。。。但在这种特殊情况下,这甚至不值得讨论。真的。

我假设您是在一台普通PC上。您的机器上最多有N个线程同时执行,其中N是CPU的内核数,因此最有可能在[1,4]范围内。加上共享列表上的争用


但更重要的是,产生一个新线程的成本远远大于进行乘法运算的成本。可以有一个线程池。。。但在这种特殊情况下,这甚至不值得讨论。真的。

如果您的任务彼此独立,您可以使用Executors框架。 请注意,如果创建的线程数不超过可供使用的CPU核数,则可以获得更快的速度

样本:

class WorkInstance {
    final int argument;
    final int result;

    WorkInstance(int argument, int result) {
        this.argument = argument;
        this.result = result;
    }

    public String toString() {
        return "WorkInstance{" +
                "argument=" + argument +
                ", result=" + result +
                '}';
    }
}

public class Main {

    public static void main(String[] args) throws IOException, ExecutionException, InterruptedException {
        int numOfCores = 4;
        final ExecutorService executor = Executors.newFixedThreadPool(numOfCores);
        List<Integer> toMultiplyBy100 = Arrays.asList(1, 3, 19);
        List<Future<WorkInstance>> tasks = new ArrayList<Future<WorkInstance>>(toMultiplyBy100.size());
        for (final Integer workInstance : toMultiplyBy100)
            tasks.add(executor.submit(new Callable<WorkInstance>() {
                public WorkInstance call() throws Exception {
                    return new WorkInstance(workInstance, workInstance * 100);
                }
            }));

        for (Future<WorkInstance> result : tasks)
            System.out.println("Result: " + result.get());

        executor.shutdown();
    }
}
类工作状态{
最后一个整型参数;
最终结果;
工作状态(int参数,int结果){
this.argument=参数;
this.result=结果;
}
公共字符串toString(){
返回“工作状态{”+
“argument=“+参数”+
“,result=“+result+
'}';
}
}
公共班机{
公共静态空间