目前,我有一个 Web 界面,用户在其中输入一些数据,例如 start_date 和 end_date,然后单击一个按钮,该按钮向 servlet Controller 发出 Ajax 请求,该 Controller 执行一个接受用户输入数据的方法并执行如下操作:
在代表具有相同结构的数据库表的值列表的 for 循环中,有一个查询,并且使用结果集完成额外的计算,即
for(int i=0; i<list.size(); i++)
{
String dbTable = "vehicle_" + list.get(i).getTableName();
Object afterComputationValue = someMethodThatQueriesDataAndReturnValue(dbTable);
}
因此,对象 afterComputationValue 被放入一个列表中,并且该列表需要返回到 servlet,然后序列化并返回给用户。
因此返回列表的方法如下所示:
private List<Object> theMethod(String startDate, String endDate)
{
List<Object> theList = new ArrayList<>();
List<AnotherObject> databaseData = SomeClass.getVehiclesList();
for(int i=0; i<list.size(); i++)
{
String dbTable = "vehicle_" + list.get(i).getTableName();
Object afterComputationValue = someMethodThatQueriesDataAndReturnValue(dbTable);
theList.put(afterComputationValue);
}
return theList;
}
不幸的是,执行这个方法需要一分多钟的时间,所以我在想,如果我利用 8 核服务器,如果该方法在一个单独的线程中计算所有查询,那么它的工作速度可能会快 8 倍.
所以,如果我是对的,我想问如何让这个方法在所有线程(它们的大小取决于列表大小)完成其任务后返回值?
最佳答案
您可以使用ExecutorService
。代码可以是这样的(代码未测试):
private List<Object> theMethod(String startDate, String endDate) {
final List<Object> theList = Collections.synchronizedList(new ArrayList<>());
final List<AnotherObject> databaseData = SomeClass.getVehiclesList();
ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
for(int i=0; i<list.size(); i++) {
final index = i;
executor.execute(new Runnable() {
@Override
public void run() {
String dbTable = "vehicle_" + list.get(index).getTableName();
ResultSet rs = someMethodThatReturnsResultSet(dbTable);
Object afterComputationValue = anotherMethodToDoSomeComputation(rs);
theList.put(afterComputationValue);
}
})
}
executor.shutdown();
try {
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
}
catch (InterruptedException e) {
// Do something
}
return theList;
}
<小时/>
来自评论:
请注意,如果一个或多个线程失败,此方法无论如何都会返回列表。如果这不是预期的行为,您必须 1) 捕获 run()
方法内的 Exception
并正确处理它,或者 2) 检查 theList
与原始列表的大小相同(如果大小不同,则出现问题)。
关于java - 执行异步任务的 java 方法的返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22974274/