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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3141158/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 16:47:47  来源:igfitidea点击:

How can a Thread return a value after finishing its job?

javamultithreading

提问by nikos1983

Let's say we have this simple example:

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

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();
    }

}

How can the Thread after finishing its job return me the String temp?

线程完成工作后如何返回字符串临时值?

回答by Redlab

You can achieve this by the Observer pattern. on finishing the thread notifies all listeners that it's finished and they can retrieve the value (through a getter). Or it can even already send the computed value.

您可以通过观察者模式实现这一点。在完成线程时通知所有侦听器它已完成并且他们可以检索值(通过 getter)。或者它甚至可以发送计算值。

Or you can use a task, see FutureTask, a runnable ( indeed as stated below a Callable ) that returns a result and can throw exceptions.

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

回答by Paul McKenzie

Look at Futureinterface javadoc. It has sample usage showing you how to do this.

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

回答by TofuBeer

Make use of the (relatively) new Callable<T>instead of Runnable (available in 1.5 and newer versions):

使用(相对)新的Callable<T>而不是 Runnable(在 1.5 和更新版本中可用):

Here is a (simple) example:

这是一个(简单的)示例:

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!");
    }
}

回答by Martin

If you don't want to swap the solution to use Callable objects then you can use also queues and return the result from the threads that way.
I re-wrote your example like this:

如果您不想将解决方案交换为使用 Callable 对象,那么您也可以使用队列并以这种方式从线程返回结果。
我像这样重写了你的例子:

import java.util.PriorityQueue;
import java.util.Queue;

public class GetResultFromThread {
    public static void main(String[] args) throws Exception {
        Queue<String> queue = new PriorityQueue<String>();
        int expectedResults = 2;
        for (int i = 0; i < expectedResults; i++) {
            new Example(queue).start();
        }

        int receivedResults = 0;
        while (receivedResults < expectedResults) {
            if (!queue.isEmpty()) {
                System.out.println(queue.poll());
                receivedResults++;
            }
            Thread.sleep(1000);
        }
    }
}

class Example extends Thread {
    private final Queue<String> results;

    public Example(Queue<String> results) {
        this.results = results;
    }

    @Override
    public void run() {
        results.add("result from thread");
    }
}

Note that you shall think of synchronization and concurrency!

请注意,您应该考虑同步和并发!