【问题标题】:Java Callable and Future not running asychronouslyJava Callable 和 Future 没有异步运行
【发布时间】:2021-12-02 17:59:20
【问题描述】:

我正在使用 Java 7。

我有一个方法我想在一个新线程中执行(异步)并允许其余的进程继续。但是,我有以下代码,但它仍然同步执行。

executeBookingAndApprovalConcurrently(autoBookingEnabled, tripDTO, approvalRequestDetails, approvalRequest, quoteResponse, tripRequirementsResponse, evaluatorsList, evaluationTree, memberId, properties, session);
logger.log(Level.INFO, "Executed booking and approval requests in a new thread." );

private void executeBookingAndApprovalConcurrently(final boolean autoBookingEnabled, final TripDTO tripDTO, final ApprovalRequestDetails approvalRequestDetails, final ApprovalRequest approvalRequest, final QuoteResponse quoteResponse, final TripRequirementsResponse tripRequirementsResponse, final List<List<Evaluator>> evaluatorsList, final List<EvaluationApprovalTree> evaluationTree, final Long memberId, final Map<String,Object> properties, final HttpSession session) {

    Callable<Void> taskBookAndApprove = new Callable<Void>() {
        public Void call() {
            executeBookingAndApproval(autoBookingEnabled, tripDTO, approvalRequestDetails, approvalRequest, quoteResponse, tripRequirementsResponse, evaluatorsList, evaluationTree, memberId, properties, session);
            return null;
        }
    };

    Future<Void> futureBookAndApprove = executorService.submit(taskBookAndApprove);
    try {
        futureBookAndApprove.get();
    } catch (InterruptedException e) {
        logger.log(Level.SEVERE, "InterruptedException Error calling executeBookingAndApproval in a new thread.", e);
    } catch (ExecutionException e) {
        logger.log(Level.SEVERE, "ExecutionException Error calling executeBookingAndApproval in a new thread.", e);
    }

}

private void executeBookingAndApproval(final boolean autoBookingEnabled, final TripDTO tripDTO, final ApprovalRequestDetails approvalRequestDetails, final ApprovalRequest approvalRequest, final QuoteResponse quoteResponse, final TripRequirementsResponse tripRequirementsResponse, final List<List<Evaluator>> evaluatorsList, final List<EvaluationApprovalTree> evaluationTree, final Long memberId, final Map<String,Object> properties, final HttpSession session) {
    // do stuff that takes a long time
    logger.log(Level.INFO, "Called executeBookingAndApproval successfully in a new thread.");
}

我想打印:

在新线程中执行预订和批准请求。

在新线程中成功调用 executeBookingAndApproval。

但它按以下顺序打印:

在新线程中成功调用 executeBookingAndApproval。

在新线程中执行预订和批准请求。

【问题讨论】:

  • Future#get() 块。
  • @sp00m 感谢您的回复。如果.get() 阻塞,我应该使用什么?
  • 你可以删除这一行。触发工作的不是Future#get(),而是executorService#submit()

标签: java multithreading callable


【解决方案1】:

executeBookingAndApprovalConcurrently 应该返回 Future,以便您可以在方法外部调用 futureBookAndApprove.get();。例如。

final Future<Void> futureBookAndApprove = executeBookingAndApprovalConcurrently(autoBookingEnabled, tripDTO, approvalRequestDetails, approvalRequest, quoteResponse, tripRequirementsResponse, evaluatorsList, evaluationTree, memberId, properties, session);
logger.log(Level.INFO, "Executed booking and approval requests in a new thread." );

try {
    futureBookAndApprove.get();
} catch (InterruptedException e) {
    logger.log(Level.SEVERE, "InterruptedException Error calling executeBookingAndApproval in a new thread.", e);
} catch (ExecutionException e) {
    logger.log(Level.SEVERE, "ExecutionException Error calling executeBookingAndApproval in a new thread.", e);
}

private Future<Void> executeBookingAndApprovalConcurrently(final boolean autoBookingEnabled, final TripDTO tripDTO, final ApprovalRequestDetails approvalRequestDetails, final ApprovalRequest approvalRequest, final QuoteResponse quoteResponse, final TripRequirementsResponse tripRequirementsResponse, final List<List<Evaluator>> evaluatorsList, final List<EvaluationApprovalTree> evaluationTree, final Long memberId, final Map<String,Object> properties, final HttpSession session) {

    return executorService.submit(() -> {
        executeBookingAndApproval(autoBookingEnabled, tripDTO, approvalRequestDetails, approvalRequest, quoteResponse, tripRequirementsResponse, evaluatorsList, evaluationTree, memberId, properties, session);
        return null; 
    });

}

当您调用get() 时,该方法会阻塞以等待响应。因此,虽然任务会异步执行,但除非您在初始 logger.log 行之后执行 get(),否则它不会按您的意愿显示。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-21
    • 2016-06-10
    • 2022-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-15
    • 1970-01-01
    相关资源
    最近更新 更多