这是可能的,但您需要稍微更改代码。检查以下类:
第一个类似于 a Runnable
,但您需要实现的方法定义为V call() throws Exception
,而不是void run()
: 它允许您返回一个值。
第二个包装 a Callable<V>
(或 aRunnable
加上一个常量返回值),并且是 aRunnable
本身,因此您可以将它传递给 aThread
就像您对Runnable
.
因此,您可以将代码更改为以下内容:
void setOff() {
final FutureTask<Boolean> ft = new FutureTask<Boolean>(new myClass());
new Thread(ft).start();
try {
System.out.println("The result is: " + ft.get());
} catch (ExecutionException e) {
System.err.println("A method executed on the background thread has thrown an exception");
e.getCause().printStackTrack();
}
}
class myClass implements Callable<Boolean> {
@Override public Boolean call() throws Exception {
// let's fake some long running computation:
Thread.sleep(1000);
return true;
}
}
调用ft.get()
只会在call()
方法完成执行后(在后台线程上)返回,因此您必须等待 1 秒才能将该行打印到控制台。
上还有许多其他有用的方法FutureTask
。检查文档。
您可能会发现其他一些有用的类:ExecutorService
及其实现,以及Executors
. 它有一个被调用的方法,该方法submit
接受 aRunnable
或 a Callable<V>
,并返回一个Future<?>
or Future<V>
,这是由 实现的接口之一FutureTask
。你会得到类似的行为。例如:
public static void main() {
final ExecutorService es = Executors.newCachedThreadPool();
final Future<Boolean> f = es.submit(new myClass());
try {
System.out.println("The result is: " + f.get());
} catch (ExecutionException e) {
System.err.println("A method executed on the background thread has thrown an exception");
e.getCause().printStackTrack();
}
es.shutdown();
}
这样做的好处是ExecutorService
将为您管理线程。它可能会创建一些线程并将它们重用于您提交的 Callables 和 Runnables:如果您有许多此类作业,这可能会提高性能,因为您将避免为每个作业创建一个线程——线程创建有一些开销!
编辑:该.get()
方法抛出一个ExecutionException
,它包装了一个在方法执行期间可能抛出的异常.call()
。要检查异常,catch
请ExecutionException
调用.getCause()
它。我刚刚添加了缺少的 try/catch 块。