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

时间:2010-06-29 13:36:28

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

}

完成作业后线程如何返回String temp?

4 个答案:

答案 0 :(得分:65)

使用(相对)新的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!");
    }
}

答案 1 :(得分:12)

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

答案 2 :(得分:8)

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

或者你可以使用一个任务,参见FutureTask,一个runnable(确实如下面一个Callable所述),它返回一个结果并且可以抛出异常。

答案 3 :(得分:0)

如果您不想交换解决方案以使用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");
    }
}

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