等待N个线程中的N-1结束,然后发出最后一个线程的指令

时间:2014-10-24 10:44:53

标签: java multithreading

所以,我为标题道歉。如果你不知道如何调用它,我很难用一句话来解释我想做什么。

因此假设我只能使用原始线程函数(wait,notify,no concurrent package)

程序有3个线程,它们都是相同的,并由主线程调用。它们表现正常,直到三个中的一个获得异常,因此它必须等待剩余的2个线程的结束才能启动恢复过程。 我在考虑一个静态变量,但我不是很确定,我希望尽可能简单。

每个帖子同时开始。

3 个答案:

答案 0 :(得分:1)

我认为您需要java.concurrent.CountdownLatch,但是如果您无法使用java.concurrent包,则可以使用Object.wait / notify和synchronized块自行编写代码。

然后可以在每个线程的finally {}中递减锁存器,如果线程完成或发生异常,则会运行该锁存器。

然后你的主程序只需等待计数变为0。

public class StackOverflow26546397 {

    static class CountdownLatch {
        private int count;
        private Object monitor = new Object();

        public CountdownLatch(int count) {
            this.count = count;
        }

        public void countDown() {
            synchronized (monitor) {
                count--;
                monitor.notifyAll();
            }
        }

        public void await() throws InterruptedException {
            synchronized (monitor) {
                while (count > 0) {
                    monitor.wait();
                }
            }
        }

    }

    static class Job implements Runnable {
        private CountdownLatch latch;

        public Job(CountdownLatch latch) {
            this.latch = latch;
        }

        @Override
        public void run() {
            try {
                // do work.
                Thread.sleep((long) (Math.random() * 3000d));
            } catch (InterruptedException e) {
                //
            } finally {
                latch.countDown();
            }
        }

    }

    public static void main(String[] args) throws InterruptedException {
        CountdownLatch latch = new CountdownLatch(3);

        new Thread(new Job(latch)).start();
        new Thread(new Job(latch)).start();
        new Thread(new Job(latch)).start();

        latch.await();
        System.out.println("All threads finished");
    }

}

答案 1 :(得分:1)

我没有看到为什么你不能像你建议的那样使用静态变量的原因。这就是我如何用内部阶级来做这件事......

private static boolean running = true;

public void test26546397() {

    while (true) {
        Thread t1 = new Thread(new MyRunnable());
        Thread t2 = new Thread(new MyRunnable());
        Thread t3 = new Thread(new MyRunnable());

        t1.start();
        t2.start();
        t3.start();

        try {
            t1.join();
            t2.join();
            t3.join();
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }

        running = true;
        // Do recovery
    }
}


public class MyRunnable implements Runnable {

    @Override
    public void run() {
        while (running) {
            try {
                // doStuff
            } catch (Exception ex) {
                running = false;
            }
        }
    }
}

我当然会用更合适的东西替换while (true)

答案 2 :(得分:0)

不确定你要做什么,但这是我能想到的那么简单(只是原生并发): 创建静态或共享volatile布尔值

private static volatile boolean exceptionOccured=false

将上述内容设置为' true'发生异常时:

....}catch(Exception e){ exceptionOccured=true; }

在正常的线程流中定期检查:

if (exceptionOccured) //enter you synchronized call here

synchronized方法可能类似于:

public synchronized void checkAndRecover(){ //decrement a counter or other logic to identify which is the last Thread and then //perform any recovery logic }