我使用了类似的程序来实现多线程来运行并行进程但是在完成几个进程之前我的线程正在转移到另一个(或)它没有完全完成这个过程,我写了5个与数据并行的文件每个线程,其中5个有时4个文件只写。请参阅我提到的相同代码,
private static final Random PRNG = new Random();
private static class Result {
private final int wait;
public Result(int code) {
this.wait = code;
}
}
public static Result compute(Object obj) throws InterruptedException {
int wait = PRNG.nextInt(3000);
Thread.sleep(wait);
return new Result(wait);
}
public static void main(String[] args) throws InterruptedException, ExecutionException
{
List<Object> objects = new ArrayList<Object>();
for (int i = 0; i < 1000; i++) {
objects.add(new Object());
}
List<Callable<Result>> tasks = new ArrayList<Callable<Result>>();
for (final Object object : objects) {
Callable<Result> c = new Callable<Result>() {
@Override
public Result call() throws Exception {
return compute(object);
}
};
tasks.add(c);
}
ExecutorService exec = Executors.newCachedThreadPool();
// some other exectuors you could try to see the different behaviours
// ExecutorService exec = Executors.newFixedThreadPool(3);
// ExecutorService exec = Executors.newSingleThreadExecutor();
try {
long start = System.currentTimeMillis();
List<Future<Result>> results = exec.invokeAll(tasks);
int sum = 0;
for (Future<Result> fr : results) {
sum += fr.get().wait;
System.out.println(String.format("Task waited %d ms",
fr.get().wait));
}
long elapsed = System.currentTimeMillis() - start;
System.out.println(String.format("Elapsed time: %d ms", elapsed));
System.out.println(String.format("... but compute tasks waited for total of %d ms; speed-up of %.2fx", sum, sum / (elapsed * 1d)));
} finally {
exec.shutdown();
}
}
我可以知道我们可以为多线程实现更好的解决方案,一旦进程完成,线程应退出进程并且我正在使用Java8,
更新了流程代码
public String compute(String obj) throws InterruptedException {
MyProcess myProc=new MyProcess(writeFiles(obj));
myProc.generateReport();
}
public void processMethod() {
List<Callable<String>> tasks = new ArrayList<Callable<String>>();
for (final String object : list) {
Callable<String> c = new Callable<String>() {
@Override
public String call() throws Exception {
return compute(object);
}
};
tasks.add(c);
}
ExecutorService exec = Executors.newCachedThreadPool();
try {
long start = System.currentTimeMillis();
List<Future<String>> results = exec.invokeAll(tasks);
String sum=null;
}
finally {
exec.shutdown();
}
try {
exec.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
} catch (InterruptedException e) {
}
}
考虑writeFiles会将数据从数据库读取和写入本地文件,这个内存很大,需要比较包含差异的5个文件,在这种情况下,一次所有文件都被写入,而其他文件只有一个文件正在写入,并且线程的总时间被共享到所有池线程,并且在持续时间内不能写入所有文件。
答案 0 :(得分:2)
这是因为Future
是否在并发或顺序中执行依赖于ExecutorService
。因此,如果您将Executors.newCachedThreadPool()
更改为Executors.newSingleThreadExecutor()
,那么任务将以顺序而非并发执行,然后已用时间< / em>与等待时间的总和几乎相同。例如:
List<Callable<Result>> tasks = asList(() -> compute(null), () -> compute(null));
ExecutorService exec = Executors.newSingleThreadExecutor();
try {
long start = System.currentTimeMillis();
List<Future<Result>> results = exec.invokeAll(tasks);
int sum = 0;
for (Future<Result> fr : results) {
sum += fr.get().wait;
System.out.println(String.format("Task waited %d ms",
fr.get().wait));
}
long elapsed = System.currentTimeMillis() - start;
System.out.println(elapsed / sum);
// ^--- 1
} finally {
exec.shutdown();
}
AND 您可以在java.util.concurrent包摘要中看到它,详细信息如下:
Executor是一个简单的标准化接口,用于定义自定义类似线程的子系统,包括线程池,异步I / O和轻量级任务框架。 取决于正在使用哪个具体的Executor类,任务可以在新创建的线程,现有任务执行线程或< strong>线程调用执行,可以执行顺序或并发。