Java线程:线程如何返回值

时间:2014-10-01 16:18:43

标签: java multithreading

我是计算机科学的大学生,我熟悉C语言中的主题。 但是在Java中,OOP让Thread难以理解。

我编写了以下程序,需要将独立线程的值返回给主程序。

主程序:

package main;

public class Main {
    public static void main(String[] args) {
            System.out.println(fibonacci(400)); 
    }

    public static int fibonacci(int x) {
        Thread p1 = new Thread( new Fibonacci(x-1));
        Thread p2 = new Thread( new Fibonacci(x-2));
        p1.start();
        p2.start();

        int result = 0;
        // Here I need the returns of the threads
        // int result = thread_value1 + thread_value2;
        return result;
    }
}

斐波纳契线程:

package main;

public class Fibonacci implements Runnable {

    int result;
    int x;

    public Fibonacci(int parameter) {
           x = parameter;
    }


    @Override
    public void run() {
        result = fib(x);
    }

    public int fib(int x) {
        if(x == 1) return 1;
        if(x == 2) return 1;
        return fib(x-1) + fib(x-2);
    }
}

2 个答案:

答案 0 :(得分:2)

正如Sotirios Delimanolis在评论中所述,您可以使用CallableExecutorService来解决此问题。见this example

另一种可能过度杀戮的替代方案,但如果线程产生多个值,则特别有用的方法是使用BlockingQueueConcurrentLinkedQueue在线程之间进行通信。这是像Akka这样的库背后的基础。

public class Main {

    BlockingQueue<Integer> queue = new LinkedBlockingQueue();

    public static int fibonacci(int x) {
        Thread p1 = new Thread( new Fibonacci(x-1, queue));
        Thread p2 = new Thread( new Fibonacci(x-2, queue));
        p1.start();
        p2.start();

        // wait for queues to have values in them, then remove the values
        int result = queue.take().intValue() + queue.take().intValue();
        return result;
    }
}

public class Fibonacci implements Runnable {

    int x;
    BlockingQueue<Integer> queue;

    public Fibonacci(int parameter, BlockingQueue queueParam) {
           x = parameter;
           queue = queueParam;
    }


    @Override
    public void run() {
        // put output in queue
        queue.offer(new Integer(fib(x)));
    }
}

答案 1 :(得分:2)

实现此目的的最简单方法是将结果保存到Fibonacci个对象中的字段,然后从那里读取它们。请注意,由于许多线程将访问此数据,因此您需要同步对这些字段的访问。在简单int值的情况下,添加volatile修饰符就足够了。如果您扩展Thread而不是提供Runnable,它也可能使代码更清晰(但这不是必需的)。所以你的代码看起来像这样:

public class FibonacciThread extends Thread {
    public volatile int result;
    int x;

    public FibonacciThread(int parameter) {
       x = parameter;
    }


    @Override
    public void run() {
        result = fib(x);
    }

    public int fib(int x) {
        if(x == 1) return 1;
        if(x == 2) return 1;
        return fib(x-1) + fib(x-2);
    }
}

main()中,您可以执行以下操作:

FibonacciThread p1 = new FibonacciThread(x-1);
FibonacciThread p2 = new FibonacciThread(x-2);
p1.start();
p2.start();

p1.join();
p2.join();
int result = p1.result + p2.result;

为了简洁起见,我正在跳过吸气剂/制定者以及任何花哨的设计。

需要调用Thread.join()才能等待线程完成,这样您就可以确保在读取其值之前计算了result字段。

相关问题