gpt4 book ai didi

java - 如何知道 Future 是使用 Callable 还是 Runnable 创建的

转载 作者:行者123 更新时间:2023-12-02 09:41:21 25 4
gpt4 key购买 nike

我正在涉足 future 。可以使用 Runnable 和 Callable 创建 Future。有没有办法决定它是如何创建的?

例如,我有以下代码:

        Future<?>       future  = null;
Future<?> future2 = null;
ExecutorService service = null;
service = Executors.newSingleThreadExecutor();
future = service.submit(() -> {
for (int i = 0; i < 5; ++i) {
System.out.println("Printing record: " + i);
Thread.sleep(5);
}
return "Done";
});
future2 = service.submit(() -> System.out.println("Printing zoo inventory"));
System.out.println("================================================================");
System.out.println(future);
System.out.println(future.get().getClass());
System.out.println(future.get());
System.out.println("================================================================");
System.out.println(future2);
try {
System.out.println(future2.get().getClass());
System.out.println(future2.get());
} catch (ExecutionException e) {
System.out.println("Could not do a get");
}
System.out.println("================================================================");

结果是:

================================================================
java.util.concurrent.FutureTask@5caf905d[Completed normally]
class java.lang.String
Done
================================================================
java.util.concurrent.FutureTask@1f32e575[Completed normally]
Exception in thread "main" java.lang.NullPointerException
at ZooInfo.main(ZooInfo.java:56)

我可以使用以下方法解决这个问题:

                    if (future2.get() == null) {
System.out.println("Made with a Runnable");
} else {
System.out.println(future2.get().getClass());
System.out.println(future2.get());
}

这样做的问题是,当 Runnable 仍然需要一些时间时,我就白等了。有没有一种方法可以确定 Future 是使用 Runnable 还是 Callable 创建的,而不需要使用 get()?

最佳答案

我不认为您真的需要知道 Future 是否是从 Runnable 创建的或Callable .

一方面,创建 Future 的方法远不止于此。 :例如CompleteableFuture不是由任何一个创建的;更一般地说,从Future开始是一个接口(interface),可以根据需要创建实例。

另一个: Future 的抽象是它在完成时给你一个(可能为空)值,或者抛出一个异常。这就是它的全部目的。

(此外,您当前检查返回值是否为空的方法并不可靠,因为 Callable.call() 允许返回 null)。

如果您需要它来做其他事情,您可能需要重新审视您的设计,以便您可以简单地按预期处理它。

<小时/>

但是,如果您确实有一个用例需要您知道它是如何创建的,那么您需要控制创建。不要让调用者直接向执行器提交代码,而是包装在这样的类中:

class YourExecutor {
// Initialize in ctor.
private final ExecutorService executor;

FromRunnable submit(Runnable r) {
return new FromRunnable(executor.submit(r));
}

<T> FromCallable<T> submit(Callable<? extends T> c) {
return new FromCallable<>(executor.submit(c));
}
}

哪里FromRunnableFromCallable<T>类是否实现 Future<Void>Future<T>分别将所有方法委托(delegate)给兼容 Future 的另一个实例(作为构造函数参数传递)。

然后您可以使用 instanceof 检查出处;或通过其他方式,例如扩展公共(public)基本案例或接口(interface),提供描述来源的方法。

但是,重申一下,更好的方法是设计代码,使其不需要知道。

关于java - 如何知道 Future 是使用 Callable 还是 Runnable 创建的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57042839/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com