说我有一个类似的任务:
for(Object object: objects) {
Result result = compute(object);
list.add(result);
}
并行化每个compute()的最简单方法是什么(假设它们已经可以并行化了)?
我不需要严格匹配上面代码的答案,而只是一个常规答案。但是,如果您需要更多信息:我的任务是IO绑定的,这是针对Spring
Web应用程序的,这些任务将在HTTP请求中执行。
我建议看一下ExecutorService。
特别是这样的事情:
ExecutorService EXEC = Executors.newCachedThreadPool();
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);
}
List<Future<Result>> results = EXEC.invokeAll(tasks);
请注意,newCachedThreadPool
如果objects
列表很大,使用可能会很糟糕。缓存的线程池可以为每个任务创建一个线程!您可能想newFixedThreadPool(n)
在n合理的地方使用(例如,假设compute()
CPU受限制,则具有的内核数)。
这是实际运行的完整代码:
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class ExecutorServiceExample {
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 < 100; 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();
}
}
}
问题内容: 现在,我有一个Java程序,其类当前为POJO,并存储在易失性内存中。这些必须坚持下去。据我了解,两个流行的选择是JDO和Java Persistence API。对于对SQL,Torque等了解甚少的人,这是向程序数据添加持久性的最简单方法? 问题答案: 序列化到文件系统的传统方法是使用Java序列化。但是,您需要在各处实现Serializable。 一个更简单的解决方案是使用XSt
最好的方法是什么?JCUDA是一个完美的映射到C CUDA还是完全不同?或者从Java调用C代码并共享结果是否有意义(链接列表是否可以访问)?
问题内容: 在Java中,数组不会覆盖toString(),因此,如果您尝试直接打印一个数组,则得到数组的十六进制,如下所示: 但是通常情况下,我们实际上会想要更多类似的东西。最简单的方法是什么?以下是一些示例输入和输出: 问题答案: 从Java 5开始,您可以;然后将或用于数组中的数组。请注意,版本调用数组中的每个对象。输出甚至以您要求的确切方式修饰。 例子: 简单数组: 输出: 嵌套数组: 输
问题内容: cgi.escape似乎是一种可能的选择。它运作良好吗?有什么更好的东西吗? 问题答案: 很好 它逃脱了: 至 至 至 对于所有HTML而言,这就足够了。 编辑:如果您有非ASCII字符,您还想转义,以便包含在使用不同编码的另一个编码文档中,如 Craig 所说,只需使用: 不要忘了解码到第一,使用任何编码它编码的。 但是根据我的经验,如果您从头开始一直都在工作,那么这种编码是没有用的
问题内容: 我想在Java SE中拥有 我必须要做些什么?我在我的项目中使用postgres数据库和maven。 我已经在阅读有关Weld的内容(但看起来只像CDI)。我不知道如何增加焊接实体管理器的可能性。我知道我可以通过获得实体管理器 但它不如注射方便。 如果有关于它的任何教程,那就太好了。无论如何,谢谢您的帮助! 问题答案: 首先,EJB是Java EE的一部分,因此您不能在Java SE中
我正在从我的应用程序中执行一个脚本,并通过Task value属性上的更改监听器用输出更新一个文本区域,但并不是所有行都显示出来。 我的问题基本上在JavaFX ChangeListener中得到了解决,并不总是有效,但我有一个后续问题。