简体   繁体   English

为什么我的threadExecutor会调用两次相同的回调?

[英]why does my threadExecutor calls the same callback twice?

i have this code: 我有这个代码:

public <T> T executeCodeBlockWithTimeLimit(String criticalBlockTimeOutMilli, Callable<T> callable) throws
        Exception {
    ExecutorService service = Executors.newSingleThreadExecutor();
    Future<T> future = service.submit(callable);

    startStopWatch();
    T result;

    if (criticalBlockTimeOutMilli != null) {
        result = future.get(Long.parseLong(criticalBlockTimeOutMilli), TimeUnit.MILLISECONDS);
    } else {
        result = callable.call();
    }
    long timeElapsed = stopStopWatch();
    e2eResult.runTime = timeElapsed;
    service.shutdown();
    return result;
}

and in outer method: 并在外部方法:

    Callable<Void> callable = new
            Callable<Void>() {
                @Override
                public Void call() throws
                        Exception {

                    System.out.println("22222");

                    return null;
                }
            };
    timerUtils.executeCodeBlockWithTimeLimit(criticalBlockTimeOutMilli, callable);

And I see the console prints 我看到控制台打印

22222
22222

why is this called twice? 这为什么叫两次?

When you get the Future from an Executor with the submit method this one calls the Callable object method and stores the result. 当您使用submit方法从Executor获取Future时,会调用Callable对象方法并存储结果。 In your code you first get Future then if the variable criticalBlockTimeOutMilli is null you call the call() method on your Callable object. 在您的代码中,您首先获得Future,然后如果变量criticalBlockTimeOutMillinull ,则在Callable对象上call()方法。 That means executing twice the Callable object. 这意味着执行两次Callable对象。

You should use the get() method instead because this one use the already collected result from your Future object (see Future#get() method ). 您应该使用get()方法,因为这个方法使用Future对象中已经收集的结果(请参阅Future#get()方法 )。

if (criticalBlockTimeOutMilli != null) {
    result = future.get(Long.parseLong(criticalBlockTimeOutMilli), TimeUnit.MILLISECONDS);
} else {
    result = future.get();
}

Maybe ExecutorService isn't clear for you, here's the javadoc for reference: http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html#submit(java.util.concurrent.Callable) 也许ExecutorService不清楚,这里是javadoc供参考: http//docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html#submit(java.util.concurrent .Callable)

When you call submit(Callable) the executor service will invoke your callable for you. 当您调用submit(Callable) ,执行程序服务将为您调用您的callable。 There's no need for you to invoke it as well. 你也没有必要调用它。

If criticalBlockTimeOutMilli is null, then the executor will invoke the callable once, and the 如果criticalBlockTimeOutMilli为null,那么执行程序将调用一次调用,然后调用

result = callable.call(); result = callable.call();

will invoke it a second time. 将再次调用它。

(?) (?)

Assuming criticalBlockTimeOutMilli, is set to null, you are calling call method twice. 假设criticalBlockTimeOutMilli设置为null,则调用call方法两次。 One with submit method via executor service as below: 一个通过执行者服务提交方法如下:

Future<T> future = service.submit(callable);

And then you call it via call method as below: 然后通过调用方法调用它,如下所示:

result = callable.call();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM