如何将参数传递给线程并获取返回值?

时间:2013-11-26 15:36:01

标签: java multithreading

public class CalculationThread implements Runnable {

    int input;
    int output;

    public CalculationThread(int input)
    {
        this.input = input;
    }

    public void run() {
        output = input + 1;
    }

    public int getResult() {
        return output;
    }
}

其他地方:

Thread thread = new Thread(new CalculationThread(1));
thread.start();
int result = thread.getResult();

当然,thread.getResult()不起作用(它试图从Thread类调用此方法)。

你得到了我想要的东西。我怎样才能在Java中实现这一目标?

5 个答案:

答案 0 :(得分:13)

这是线程池的工作。您需要创建Callable<R>Runnable返回一个值并将其发送到线程池。

此操作的结果是Future<R>,它是指向此作业的指针,它将包含计算值,如果作业失败则不会。

public static class CalculationJob implements Callable<Integer> {
    int input;

    public CalculationJob(int input) {
        this.input = input;
    }

    @Override
    public Integer call() throws Exception {
        return input + 1;
    }
}

public static void main(String[] args) throws InterruptedException {
    ExecutorService executorService = Executors.newFixedThreadPool(4);

    Future<Integer> result = executorService.submit(new CalculationJob(3));

    try {
        Integer integer = result.get(10, TimeUnit.MILLISECONDS);
        System.out.println("result: " + integer);
    } catch (Exception e) {
        // interrupts if there is any possible error
        result.cancel(true);
    }

    executorService.shutdown();
    executorService.awaitTermination(1, TimeUnit.SECONDS);
}

打印:

result: 4

答案 1 :(得分:5)

您正在寻找Callable。它是类固醇的Runnable,它可以返回结果。检查javadoc:http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Callable.html

这是一个教程:http://www.journaldev.com/1090/java-callable-future-example

答案 2 :(得分:1)

老派风格

public class CalculationThread extends Thread {

    int input;
    int output;

    public CalculationThread(int input){
        this.input = input;
    }

    public void run() {
        output = input + 1;
    }

    public int getResult() {
        return output;
    }
}

CalculationThread thread = new CalculationThread(1);
thread.start();
thread.join();
int result = thread.getResult();

答案 3 :(得分:0)

使用构造函数并通过引用传递值。

public CalculationThread(int[] input)

您是否希望将int的值传递给名为CalculationThread的线程,您应该创建一个线程但是如果按值传递参数,则线程可以使用该值,但是您无法获取数据回来了。通过引用传递它可以修改线程中的值而不是引用,如果两个线程都可以使用引用,则可以修改两个线程中可修改的值。因为您应该同步代码以共享相同的引用。

答案 4 :(得分:0)

接受的答案很棒。但这不是最简单的方法。如果您只想等待线程的结果,则不需要使用ExecutorService。您只需使用java.util.concurrent.FutureTask,它基本上是Runnable包裹Callable,它也会实现Future接口。

因此,步骤1仍然使计算成为Callable

public class Calculation implements Callable<Integer> {

    private final int input;

    public Calculation(int input) {
        this.input = input;
    }

    @Override
    public Integer call() throws Exception {
        return input + 1;
    }
}

因此,您需要进行异步计算:

    FutureTask<Integer> task = new FutureTask<>(new Calculation(1561));
    new Thread(task).start();

    // ... do other stuff

    // when I really need the result :

    try {
        int result = task.get(); // this will wait for the task to finish, if it hasn't yet.
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    } catch (ExecutionException e) {
        e.getCause().printStackTrace(); // e.getCause() holds the exception that happened on the calculation thread
    }

ExecutorService添加的是管理一个线程池来运行任务,但在ExecutorService的引擎下,基本上会发生同样的事情。