Как я приостанавливаюсь основной (), пока все другие потоки не умерли?

В моей программе я создаю несколько потоков в основном () метод. Последняя строка в основном методе является вызовом к System.out.println (), который я не хочу называть, пока все потоки не умерли. Я попытался назвать Thread.join () на каждом потоке однако, который блокируют каждый поток так, чтобы они выполнились последовательно вместо параллельно.

Существует ли способ заблокировать основное () поток, пока все другие потоки не закончили выполняться? Вот соответствующая часть моего кода:

public static void main(String[] args) {

//some other initialization code

//Make array of Thread objects
Thread[] racecars = new Thread[numberOfRaceCars];

//Fill array with RaceCar objects
for(int i=0; i<numberOfRaceCars; i++) {
    racecars[i] = new RaceCar(laps, args[i]);
}

//Call start() on each Thread
for(int i=0; i<numberOfRaceCars; i++) {
    racecars[i].start();
    try {
        racecars[i].join(); //This is where I tried to using join()
                            //It just blocks all other threads until the current                            
                            //thread finishes.
    } catch(InterruptedException e) {
        e.printStackTrace();
    }
}

//This is the line I want to execute after all other Threads have finished
System.out.println("It's Over!");

}

Спасибо за парней справки!

Eric

23
задан ericso 12 March 2010 в 21:51
поделиться

6 ответов

Вы запускаете свои потоки и сразу же ждете их завершения (используя join()). Вместо этого следует выполнить join() вне цикла for в другом цикле for, например:

// start all threads
for(int i=0; i<numberOfRaceCars; i++) {
    racecars[i].start();
}
// threads run... we could yield explicity to allow the other threads to execute
// before we move on, all threads have to finish
for(int i=0; i<numberOfRaceCars; i++) {
    racecars[i].join(); // TODO Exception handling
}
// now we can print
System.out.println("It's over!");
46
ответ дан 29 November 2019 в 01:18
поделиться

Вы можете использовать метод соединения. См. Документацию здесь

1
ответ дан 29 November 2019 в 01:18
поделиться

Вы можете wait() в вашем главном потоке и заставить все потоки выдать notifyAll(), когда они закончат. Тогда каждый раз, когда ваш главный поток будет пробуждаться таким образом, он сможет проверить, жив ли еще хотя бы один поток, и тогда вы wait() еще немного.

2
ответ дан 29 November 2019 в 01:18
поделиться

Вы можете добавить хук выключения для сообщения "Its Over". Таким образом, оно будет выдаваться при завершении программы, и вам не придется ждать каждый поток.

1
ответ дан 29 November 2019 в 01:18
поделиться

Можно сделать так, чтобы последняя строка находилась в потоке "мониторинга". Он будет проверять время от времени, что он единственный запущенный поток и состояние завершения == true, и затем может сработать, если это так. Тогда он мог бы делать другие вещи, кроме println

0
ответ дан 29 November 2019 в 01:18
поделиться

Вы можете разделить объект CyclicBarrier между вашими RaceCarами и главным потоком, и заставить потоки RaceCar вызывать await(), как только они выполнят свою задачу. Постройте барьер с количеством потоков RaceCar плюс один (для главного потока). Главный поток продолжит работу, когда все RaceCarы закончат работу. См. http://java.sun.com/javase/6/docs/api/java/util/concurrent/CyclicBarrier.html

Подробнее, постройте CyclicBarrier в главном потоке и добавьте барьер. await() в класс RaceCar непосредственно перед выходом метода run(), а также добавьте вызов barrier.await() перед вызовом System.out.println() в главном потоке.

6
ответ дан 29 November 2019 в 01:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: