线程如何在完成工作后返回值?

nik*_*983 45 java multithreading

假设我们有这个简单的例子:

public Example extends Thread{

    String temp;    

    public Example(){
    }

    @Override
    public void run(){
        .
        .
        .
        .
        temp = "a_value";
    }

    public static void main(String[] args) {

        Example th = new Example();
        th.start();
    }

}
Run Code Online (Sandbox Code Playgroud)

Thread完成工作后怎么能给我返回String temp?

Tof*_*eer 65

使用(相对)new Callable<T>而不是Runnable(1.5及更新版本):

这是一个(简单)示例:

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;


public class Main {

    public static void main(final String[] argv) {
        final ExecutorService service;
        final Future<String>  task;

        service = Executors.newFixedThreadPool(1);        
        task    = service.submit(new Foo());

        try {
            final String str;

            // waits the 10 seconds for the Callable.call to finish.
            str = task.get(); // this raises ExecutionException if thread dies
            System.out.println(str);
        } catch(final InterruptedException ex) {
            ex.printStackTrace();
        } catch(final ExecutionException ex) {
            ex.printStackTrace();
        }

        service.shutdownNow();
    }
}

class Foo implements Callable<String> {
    public String call() {
        try {
            // sleep for 10 seconds
            Thread.sleep(10 * 1000);
        } catch(final InterruptedException ex) {
            ex.printStackTrace();
        }

        return ("Hello, World!");
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 相对于发布...... 1.6是当前的,它是在1.5中发布的.与1.0中的那个相比,那些学生从中学到的很多书都没有Callable. (20认同)
  • 在例子中我总是想知道wtf是foo (8认同)
  • "(相对)新"相对于什么?它是在一个现已完成其服务终止期限的版本中引入的. (2认同)
  • foo是BigBang Theory中软件程序员的"Baznga"版本:) (2认同)
  • @TofuBeer 你能不能帮忙给线程方法 call() 提供输入:-) (2认同)
  • @Mohit 你不能,因为 API 不允许你 https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Callable.html#call-- 你能做什么相反,在 Foo 中创建成员变量并在构造函数中设置它们,然后在调用方法中使用它们。例如; task = service.submit(new Foo(1,"abc")); (2认同)

Pau*_*zie 12

看看Future接口javadoc.它有示例用法,向您展示如何执行此操作.


Red*_*lab 8

您可以通过Observer模式实现此目的.在完成线程时通知所有听众它已完成并且他们可以检索值(通过getter).或者它甚至可以发送计算值.

或者您可以使用任务,请参阅FutureTask,一个可运行的(实际上如下所述的Callable),它返回一个结果并可以抛出异常.