针对这样的情况动态生成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+
'}';
}
}
公共班机{
公共静态空间