java - 执行异步任务的 java 方法的返回值

标签 java multithreading asynchronous multiprocessing

目前,我有一个 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/

相关文章:

c# - 是否需要 relaycommand 的异步版本才能正确运行异步方法

javascript异步调用和单线程模型

java - android 计划的作业是否在应用程序升级后仍然存在?

android - 互联网连接检查线程 Android

multithreading - 为什么这个简单的 Lua 协程不起作用?

java - 在 Java 中重新分配列表是线程安全的吗?

java - 那个 "selector"叫什么?

java - 两个二元矩阵的交错

java - TreeView 的 Primefaces 验证

java - 如何使用 CompletableFuture 打开列表中的所有结果并将其收集到线程中?