繁体   English   中英

Java线程:线程如何返回值

[英]Java threads: how do threads return values

我是计算机科学的大学生,并且熟悉C语言中的线程。但是,在Java中,OOP使线程难以理解。

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

主程序:

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

正如Sotirios Delimanolis在评论中指出的那样,您可以为此使用CallableExecutorService ,例如,请参见此示例

在这里可能过大的另一种选择,但是如果线程产生多个值,则特别有用,它是使用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)));
    }
}

实现此目的的最简单方法是将结果保存到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;

为了简洁起见,我跳过了getter / setter和任何精美的设计。

为了等待线程完成,需要对Thread.join()调用,以便可以确保在读取result字段之前已计算出result字段。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM