Wait until any of Future is done

前端 未结 8 1081
长发绾君心
长发绾君心 2021-02-01 01:09

I have few asynchronous tasks running and I need to wait until at least one of them is finished (in the future probably I\'ll need to wait util M out of N tasks are finished). C

相关标签:
8条回答
  • 2021-02-01 01:37

    This is actually pretty easy with wait() and notifyAll().

    First, define a lock object. (You can use any class for this, but I like to be explicit):

    package com.javadude.sample;
    
    public class Lock {}
    

    Next, define your worker thread. He must notify that lock object when he's finished with his processing. Note that the notify must be in a synchronized block locking on the lock object.

    package com.javadude.sample;
    
    public class Worker extends Thread {
        private Lock lock_;
        private long timeToSleep_;
        private String name_;
        public Worker(Lock lock, String name, long timeToSleep) {
            lock_ = lock;
            timeToSleep_ = timeToSleep;
            name_ = name;
        }
        @Override
        public void run() {
            // do real work -- using a sleep here to simulate work
            try {
                sleep(timeToSleep_);
            } catch (InterruptedException e) {
                interrupt();
            }
            System.out.println(name_ + " is done... notifying");
            // notify whoever is waiting, in this case, the client
            synchronized (lock_) {
                lock_.notify();
            }
        }
    }
    

    Finally, you can write your client:

    package com.javadude.sample;
    
    public class Client {
        public static void main(String[] args) {
            Lock lock = new Lock();
            Worker worker1 = new Worker(lock, "worker1", 15000);
            Worker worker2 = new Worker(lock, "worker2", 10000);
            Worker worker3 = new Worker(lock, "worker3", 5000);
            Worker worker4 = new Worker(lock, "worker4", 20000);
    
            boolean started = false;
            int numNotifies = 0;
            while (true) {
                synchronized (lock) {
                    try {
                        if (!started) {
                            // need to do the start here so we grab the lock, just
                            //   in case one of the threads is fast -- if we had done the
                            //   starts outside the synchronized block, a fast thread could
                            //   get to its notification *before* the client is waiting for it
                            worker1.start();
                            worker2.start();
                            worker3.start();
                            worker4.start();
                            started = true;
                        }
                        lock.wait();
                    } catch (InterruptedException e) {
                        break;
                    }
                    numNotifies++;
                    if (numNotifies == 4) {
                        break;
                    }
                    System.out.println("Notified!");
                }
            }
            System.out.println("Everyone has notified me... I'm done");
        }
    }
    
    0 讨论(0)
  • 2021-02-01 01:40

    Why not just create a results queue and wait on the queue? Or more simply, use a CompletionService since that's what it is: an ExecutorService + result queue.

    0 讨论(0)
提交回复
热议问题