Java – 将工作分解到多个线程
|
我遇到了以下问题:为了执行性能原因,我需要跨多个线程分割工作,但我不知道采取什么方法. 首先,我将提供的任务应该返回一个值并获取一个参数.另外,主要方法(做主工作,而不是静态main())已经在单独的线程上运行,并且被定期调用.此外,该方法必须在某个时间点等待所有线程完成,然后继续. 一种方法(对我来说最明显的)是在单独的线程上安排每个作业,并将结果存储在类vars中: public Object result1,result2;
public void mainMethod() throws InterruptedException {
final Thread thread = new Thread(new Runnable() {
@Override
public void run() {
result1 = expensiveMethod("param1");
}
});
final Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
result2 = expensiveMethod("param2");
}
});
thread1.join();
thread.join();
//Do rest of work
}
private Object expensiveMethod(Object param){
// Do work and return result
}
这是一个有点丑陋,不太理想,因为正如我所说,mainMethod被调用了很多次,我不想要任何比赛条件设置结果变量.理想情况下,我想使它们成为局部变量,但是我无法使用它们在run方法中访问,除非它们是final,然后我无法为它们赋值. 其他方法我虽然在做是这样的: public void mainMethod() throws InterruptedException,ExecutionException {
String obj1,obj2;
final ExecutorService executorService = Executors.newFixedThreadPool(16);
final Future<String> res1 = executorService.submit(new Callable<String>() {
@Override
public String call() throws Exception {
return expensiveMethod("param1");
}
});
final Future<String> res2 = executorService.submit(new Callable<String>() {
@Override
public String call() throws Exception {
return expensiveMethod("param2");
}
});
obj1 = res1.get();
obj2 = res2.get();
}
private String expensiveMethod(String param) {
// Do work and return result
}
这可以从main方法自动等待这两个计算,并允许我在本地存储结果.你们怎么想?任何其他方法? 解决方法您使用ExecutorService的方法几乎是最现代和最安全的方法.只需提取您的Callable来分离课程:public class ExpensiveTask implements Callable<String> {
private final String param;
public ExpensiveTask(String param) {
this.param = param;
}
@Override
public String call() throws Exception {
return expensiveMethod(param);
}
}
这将使您的代码更清洁: final ExecutorService executorService = Executors.newFixedThreadPool(16);
final Future<String> res1 = executorService.submit(new ExpensiveTask("param1");
final Future<String> res2 = executorService.submit(new ExpensiveTask("param2");
String obj1 = res1.get();
String obj2 = res2.get();
几个注释: > 16个线程太多了,如果你只想同时处理两个任务 – 或者你想从多个客户端线程重用该池? 如果您需要完全不同的设计思想,请查看akka及其基于actor的并发模型). (编辑:鄂州站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
