Java线程等待值

Java线程等待值,java,multithreading,wait,Java,Multithreading,Wait,我有以下情况: 为了运行一个算法,我必须运行几个线程,每个线程都会在它死之前设置一个实例变量x。问题是这些线程不会立即返回: public Foo myAlgorithm() { //create n Runnables (n is big) //start these runnables (may take long time do die) //i need the x value of each runnable here, but they havent fin

我有以下情况:

为了运行一个算法,我必须运行几个线程,每个线程都会在它死之前设置一个实例变量x。问题是这些线程不会立即返回:

public Foo myAlgorithm()
{
    //create n Runnables (n is big)
    //start these runnables (may take long time do die)

    //i need the x value of each runnable here, but they havent finished yet!

    //get average x from all the runnables

    return new Foo(averageX);
}
我应该使用等待通知吗?还是我应该嵌入一个while循环并检查终止


谢谢大家

你可以向
java.util.concurrent.Future
和所有相关的东西,如线程池、执行器等了解你自己。
Future
是一个带有返回值的线程。

你可以向
java.util.concurrent.Future
和所有相关的东西,如线程池,执行者等:一个
未来
是一个具有返回值的线程。

创建一些共享存储来保存每个线程的
x
值,或者如果足够的话只存储总和。使用等待线程终止。完成后,每个线程都会调用,
myAlgorithm
方法将使用该方法等待它们

编辑:以下是我建议的方法的完整示例。它创建了39个工作线程,每个线程向共享和中添加一个随机数。当所有工人完成后,计算并打印平均值

import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;

class Worker implements Runnable {

    private final AtomicInteger sum;
    private final CountDownLatch latch;

    public Worker(AtomicInteger sum, CountDownLatch latch) {
        this.sum = sum;
        this.latch = latch;
    }

    @Override
    public void run() {
        Random random = new Random();

        try {
            // Sleep a random length of time from 5-10s
            Thread.sleep(random.nextInt(5000) + 5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // Compute x
        int x = random.nextInt(500);

        // Add to the shared sum
        System.out.println("Adding " + x + " to sum");
        sum.addAndGet(x);

        // This runnable is finished, so count down
        latch.countDown();
    }
}

class Program {

    public static void main(String[] args) {
        // There will be 39 workers
        final int N = 39;

        // Holds the sum of all results from all workers
        AtomicInteger sum = new AtomicInteger();
        // Tracks how many workers are still working
        CountDownLatch latch = new CountDownLatch(N);

        System.out.println("Starting " + N + " workers");

        for (int i = 0; i < N; i++) {
            // Each worker uses the shared atomic sum and countdown latch.
            Worker worker = new Worker(sum, latch);

            // Start the worker
            new Thread(worker).start();
        }

        try {
            // Important: waits for all workers to finish.
            latch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // Compute the average
        double average = (double) sum.get() / (double) N;

        System.out.println("    Sum: " + sum.get());
        System.out.println("Workers: " + N);
        System.out.println("Average: " + average);
    }

}
编辑:只是为了好玩,下面是一个使用和的示例


创建一些共享存储来保存每个线程的
x
值,或者如果足够的话只存储总和。使用等待线程终止。完成后,每个线程都会调用,
myAlgorithm
方法将使用该方法等待它们

编辑:以下是我建议的方法的完整示例。它创建了39个工作线程,每个线程向共享和中添加一个随机数。当所有工人完成后,计算并打印平均值

import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;

class Worker implements Runnable {

    private final AtomicInteger sum;
    private final CountDownLatch latch;

    public Worker(AtomicInteger sum, CountDownLatch latch) {
        this.sum = sum;
        this.latch = latch;
    }

    @Override
    public void run() {
        Random random = new Random();

        try {
            // Sleep a random length of time from 5-10s
            Thread.sleep(random.nextInt(5000) + 5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // Compute x
        int x = random.nextInt(500);

        // Add to the shared sum
        System.out.println("Adding " + x + " to sum");
        sum.addAndGet(x);

        // This runnable is finished, so count down
        latch.countDown();
    }
}

class Program {

    public static void main(String[] args) {
        // There will be 39 workers
        final int N = 39;

        // Holds the sum of all results from all workers
        AtomicInteger sum = new AtomicInteger();
        // Tracks how many workers are still working
        CountDownLatch latch = new CountDownLatch(N);

        System.out.println("Starting " + N + " workers");

        for (int i = 0; i < N; i++) {
            // Each worker uses the shared atomic sum and countdown latch.
            Worker worker = new Worker(sum, latch);

            // Start the worker
            new Thread(worker).start();
        }

        try {
            // Important: waits for all workers to finish.
            latch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // Compute the average
        double average = (double) sum.get() / (double) N;

        System.out.println("    Sum: " + sum.get());
        System.out.println("Workers: " + N);
        System.out.println("Average: " + average);
    }

}
编辑:只是为了好玩,下面是一个使用和的示例

使用a并将每个任务(作为a)提交给它

提交的每项任务都将为您带来未来

List<Future<ResultType>> results = exec.invokeAll(tasks);//tasks is a set of Callable<ResultType>
//invokeAll blocks untill all tasks are finished
for(Future<ResultType> f:results){
    ResultType x=f.get();//loop over Futures to get the result
    //do something with x
}
List results=exec.invokeAll(任务)//任务是一组可调用的
//调用所有块,直到所有任务完成
对于(未来f:结果){
ResultType x=f.get();//循环遍历期货以获取结果
//用x做点什么
}
使用a并将每个任务(作为a)提交给它

提交的每项任务都将为您带来未来

List<Future<ResultType>> results = exec.invokeAll(tasks);//tasks is a set of Callable<ResultType>
//invokeAll blocks untill all tasks are finished
for(Future<ResultType> f:results){
    ResultType x=f.get();//loop over Futures to get the result
    //do something with x
}
List results=exec.invokeAll(任务)//任务是一组可调用的
//调用所有块,直到所有任务完成
对于(未来f:结果){
ResultType x=f.get();//循环遍历期货以获取结果
//用x做点什么
}

初始化为N的CountDownLatch可用于使一个线程等待,直到N个线程完成某个操作,或者某个操作已完成N次。这正是我需要的!谢谢你们!初始化为N的倒计时锁存器可用于使一个线程等待N个线程完成某个操作,或者某个操作已完成N次。这正是我需要的!谢谢你们!哼,看起来比倒计时闩锁更简单。期待这个,谢谢!哼,看起来比倒计时闩锁更简单。期待这个,谢谢!太神了我会把这个留作参考。我正在编写一个遗传算法来玩俄罗斯方块,所有的代理都必须完成它们的游戏才能彼此交配,这样种群才能进化。每个游戏将在不同的线程中运行,感谢您的时间,这个java.util.concurrent API是一个救命稻草!还有一个问题:倒计时锁存还是线程池,哪种方式看起来更快?或者根本没有区别?谢谢在我提供的示例中,倒计时锁存器更快。原因是在CountDownLatch示例中,所有线程都是一次生成的。在ExecutorService示例中,一次最多可以运行10个线程,因为这是我选择的
池大小。如果在ExecutorService示例中将
POOL\u SIZE
设置为39,结果应该与CountDownLatch示例几乎相同。太棒了!我会把这个留作参考。我正在编写一个遗传算法来玩俄罗斯方块,所有的代理都必须完成它们的游戏才能彼此交配,这样种群才能进化。每个游戏将在不同的线程中运行,感谢您的时间,这个java.util.concurrent API是一个救命稻草!还有一个问题:倒计时锁存还是线程池,哪种方式看起来更快?或者根本没有区别?谢谢在我提供的示例中,倒计时锁存器更快。原因是在CountDownLatch示例中,所有线程都是一次生成的。在ExecutorService示例中,一次最多可以运行10个线程,因为这是我选择的
池大小。如果在ExecutorService示例中将
POOL_SIZE
设置为39,则结果应该与CountDownLatch示例几乎相同。
List<Future<ResultType>> results = exec.invokeAll(tasks);//tasks is a set of Callable<ResultType>
//invokeAll blocks untill all tasks are finished
for(Future<ResultType> f:results){
    ResultType x=f.get();//loop over Futures to get the result
    //do something with x
}