Я хочу достичь следующего: Когда мое приложение запустится, основной поток запустит 1+ рабочих потоков, которые должны работать в фоновом режиме, и периодически делать вещи за кулисами. Они не должны блокировать основной поток: когда главные запускают рабочий, она продолжает делать свое дело до:Как управлять жизненными циклами рабочего потока, когда основной поток Java завершается?
- главного поток отделки (нормальное завершение работы приложения) - в случае утилиты командной строки это когда достигается конец метода
main(String[])
; в случае качания GUI это может быть, когда пользователь выбирает менюFile >> Exit
и т.д. - Операционная система бросает убить команду (SIGKILL и т.д.)
- Неожиданное, неперехваченное исключение происходит в основном потоке, эффективно убивает его (это просто unpolite версия # 1 выше)
После запуска/представлен от основного потока, я хочу, чтобы все рабочие потоки (Runnable
ы), по существу, имеют свой собственный жизненный цикл, и существует независимо от основного потока. Но, если основной поток замирает в любое время, я хочу, чтобы можно было заблокировать (если это вообще возможно) основной поток, пока все рабочие не закончатся, и затем «разрешить» основной поток умереть.
Моя лучшая попытка до сих пор, хотя я знаю, что недостающие кусочки здесь и там:
public class MainDriver {
private BaneWorker baneWorker;
private ExecutorService executor = Executors.newCachedThreadPool();
public static void main(String[] args) {
MainDriver driver = new MainDriver();
driver.run();
// We've now reached the end of the main method. All workers should block while they shutdown
// gracefully (if at all possible).
if(executor.awaitTermination(30, TimeUnit.SECONDS))
System.out.println("Shutting down...");
else {
System.out.println("Forcing shut down...");
executor.shutdownNow();
}
}
private void run() {
// Start all worker threads.
baneWorker = new BaneWorker(Thread.currentThread());
// More workers will be used once I get this simple example up and running...
executor.submit(baneWorker);
// Eventually submit the other workers here as well...
// Now start processing. If command-line utility, start doing whatever the utility
// needs to do. If Swing GUI, fire up a parent JFrame and draw the application to the
// screen for the user, etc.
doStuff();
}
private void doStuff() {
// ??? whatever
}
}
public class BaneWorker implements Runnable {
private Timer timer;
private TimerTask baneTask;
private Thread mainThread;
public BaneWorker(Thread mainThread) {
super();
this.mainThread = mainThread;
}
@Override
public void run() {
try {
timer = new Timer();
baneTask = new TimerTask() {
@Override
public void run() {
System.out.println("When the main thread is ashes...");
}
};
// Schedule the baneTask to kick off every minute starting now.
timer.scheduleAtFixedRate(baneTask, new Date(), 60 * 1000);
} catch(InterruptedException interrupt) {
// Should be thrown if main thread dies, terminates, throws an exception, etc.
// Should block main thread from finally terminating until we're done shutting down.
shutdown();
}
}
private void shutdown() {
baneTask.cancel();
System.out.println("...then you have my permission to die.");
try {
mainThread.join();
} catch(InterruptedException interrupt) {
interrupt.printStackTrace;
}
}
}
Я на трассе или поодаль базы здесь? Что мне нужно изменить, чтобы сделать эту работу так, как мне это нужно? Я новичок в параллелизме Java и стараюсь использовать API параллелизма правильно, но немного спотыкаюсь. Есть идеи? Заранее спасибо!
0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [this] (http://arashmd.blogspot.com/2013/07/java-thread-example.html#fe) Пример: некоторые из них работают, поток main ждет, а затем присоединяется, а затем завершает работу системы –
Я не уверен, что вы хотите mainthread.join() в своем потоке. Это приведет к тому, что дочерние потоки ожидают выхода основного потока. Я думал, вы хотите, чтобы главный поток подождал, пока дети не выйдут. –
Спасибо @ user2511414 и Тони Эннис (+1 каждый). Подумайте об этом, если все мои работники на самом деле «Runnable's», я не думаю, что могу использовать «Thread # join()» на них. Я думаю, что единственное, что я могу сделать, это вызвать 'executor # awaitTermination (...)'. ** Это правда? ** Спасибо за любое разъяснение здесь! –