为什么让Runnable.run()方法不返回任何输出



我试图理解为什么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方法的接口等效:-)

欢呼,

最新更新