Java Callable:比单线程进程花费的时间多
Java Callable : Time taken more than a single thread process
我有以下示例代码。
import java.util.*;
import java.lang.*;
import java.io.*;
import java.util.concurrent.*;
public class CalculationThread implements Callable<Long> {
public Long call() throws Exception {
long k=0L;
for(int i=0;i<100000;i++){
for(int j=0;j<50;j++){
k=i+j;
}
}
return k;
}
public static void main(String[] args) throws InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(4);
long startTime = System.nanoTime();
for(int lo=0;lo<5000;lo++){
Future<Long> result = executorService.submit(new CalculationThread());
try {
Long l = result.get();
} catch (Exception e) {
result.cancel(true);
}
}
long endTime = System.nanoTime();
System.out.println("Using threads took "+(endTime - startTime) + " ns");
executorService.shutdown();
executorService.awaitTermination(1, TimeUnit.SECONDS);
long k=0L;
startTime = System.nanoTime();
for(int lo=0;lo<5000;lo++){
for(int i=0;i<100000;i++){
for(int j=0;j<50;j++){
k=i+j;
}
}
}
endTime = System.nanoTime();
System.out.println("Generally it takes "+(endTime - startTime) + " ns");
}
}
输出与
一样分散
Using threads took 101960490 ns
Generally it takes 143107865 ns
到
Using threads took 245339720 ns
Generally it takes 149699885 ns
可以注意到第二行几乎不变,而线程版本变化很大。为什么会这样呢?可以做些什么来减少可变性?如果我是 Java 多线程的新手,请告诉我是否在做一些愚蠢的事情。
Future#get 阻塞,直到您的可调用完成。所以主线程向池提交一个 Callable,然后等待它完成,然后再提交下一个。您有创建池的四个线程的开销,然后在创建可调用对象的线程和对象创建之间进行上下文切换(在丢弃可调用对象时进行垃圾收集),然后您不执行任何操作工作同时进行。
您如何在使用池的版本更快的情况下获得数字令人费解。当我在本地 运行 这个(以及制作 MVCE 的好工作,顺便说一句,我可以不做任何更改地复制和粘贴并且它有效)我得到的线程池部分的数字一直更高,它需要大约 3 倍的时间作为单线程代码。
我有以下示例代码。
import java.util.*;
import java.lang.*;
import java.io.*;
import java.util.concurrent.*;
public class CalculationThread implements Callable<Long> {
public Long call() throws Exception {
long k=0L;
for(int i=0;i<100000;i++){
for(int j=0;j<50;j++){
k=i+j;
}
}
return k;
}
public static void main(String[] args) throws InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(4);
long startTime = System.nanoTime();
for(int lo=0;lo<5000;lo++){
Future<Long> result = executorService.submit(new CalculationThread());
try {
Long l = result.get();
} catch (Exception e) {
result.cancel(true);
}
}
long endTime = System.nanoTime();
System.out.println("Using threads took "+(endTime - startTime) + " ns");
executorService.shutdown();
executorService.awaitTermination(1, TimeUnit.SECONDS);
long k=0L;
startTime = System.nanoTime();
for(int lo=0;lo<5000;lo++){
for(int i=0;i<100000;i++){
for(int j=0;j<50;j++){
k=i+j;
}
}
}
endTime = System.nanoTime();
System.out.println("Generally it takes "+(endTime - startTime) + " ns");
}
}
输出与
一样分散Using threads took 101960490 ns
Generally it takes 143107865 ns
到
Using threads took 245339720 ns
Generally it takes 149699885 ns
可以注意到第二行几乎不变,而线程版本变化很大。为什么会这样呢?可以做些什么来减少可变性?如果我是 Java 多线程的新手,请告诉我是否在做一些愚蠢的事情。
Future#get 阻塞,直到您的可调用完成。所以主线程向池提交一个 Callable,然后等待它完成,然后再提交下一个。您有创建池的四个线程的开销,然后在创建可调用对象的线程和对象创建之间进行上下文切换(在丢弃可调用对象时进行垃圾收集),然后您不执行任何操作工作同时进行。
您如何在使用池的版本更快的情况下获得数字令人费解。当我在本地 运行 这个(以及制作 MVCE 的好工作,顺便说一句,我可以不做任何更改地复制和粘贴并且它有效)我得到的线程池部分的数字一直更高,它需要大约 3 倍的时间作为单线程代码。