我试图理解为什么Runnable.run
方法不接受任何输入,不返回任何输出?
我理解线程的局部变量(引用或原语)必须来自自己的堆栈,但系统可以被初始化。换句话说,我不认为这在技术上是不可能的(但我可能错了)。
返回一些有用的东西,并且由Callable支持,它可以返回一个对象。
Future<MyReturnType> ret = executor.submit(new Callable<MyReturnType>() {
public MyReturnType call() throws Exception {
// do something
return new MyReturnType(value1, value2 ...);
}
});
正如你所看到的,Callable可以返回一个值,因为ExecutorService支持通过Future对象将值传递回线程。这只是在Java 5.0中添加的,所以在此之前,让Runnable
返回一个值是没有用的,因为这个返回值没有地方可去。
Runnable不需要任何参数,因为它是一个可以容纳任意数量字段的对象。例如
static void bgLog(final Level level, final String message, final Throwable t) {
logExec.submit(new Runnable() {
// the anonymous nested class implicitly holds a copy of the final arguments above.
public void run() {
LOG.log(level, message, t);
}
});
}
可以看到,run()方法可以使用任意数量的隐式传递的值,因为Runnable是一个对象,而不仅仅是一个方法的持有者。
A Runnable
是这样的,你可能正在寻找的是一个Callable
代替,它通过它的call()
方法返回一个值。这不是真的,你不能传递参数给Runnable
:它只是取决于你的接口实现。Callable
也一样。
Java有很多设施可以使Callable
异步运行:参见ExecutorService
。
Runnable
的契约使其成为构建高级抽象的完美原材料。它是关注点分离原则的一个很好的例子。
Runnable
的主要设计目标是表示一个新的执行线程的入口点。它不代表一个函数,甚至不代表一个计算:只是在另一个线程上运行的代码。考虑到这一点,void run()
方法签名是完全有意义的。如果它接受参数,那只会给不想传递参数的许多用例带来负担。
void返回值的情况甚至更清楚:一旦线程启动,它就没有任何报告对象,因此返回值的概念将只是一个附加。
你想要什么?
实际上,实现Runnable
的类可以用构造函数初始化,这给了您做任何事情的绝对自由。初始化。至于不返回任何东西,总是有Callable
接口,它允许返回值。
也许你应该把它们看作是void和非void方法的接口等效:-)
欢呼,