如何捕获Java连接线程中每个子进程的“已终止”事件

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何捕获Java连接线程中每个子进程的“已终止”事件相关的知识,希望对你有一定的参考价值。

我有“n”个线程“加入”,我想知道每个线程何时结束。

我写了这段代码,但我得到的状态是“RUNNABLE,TIMED_WAITING等”。但不是“完成”。预计会被“完成”线程抛出(至少)。

       for (index = 0; index < MAX_ITEMS; index++){                  
            try {
                pan = panes[index];

                ThreadAmasar amasar = new ThreadAmasar(pan, tc);
                ThreadPreparar preparar = new ThreadPreparar(pan, tc);
                ThreadHornear hornear = new ThreadHornear(pan, tc);
                ThreadFinish finish = new ThreadFinish(pan, tc);

                preparar.SetParent(amasar);
                hornear.SetParent(preparar);
                finish.SetParent(hornear);

                Thread.sleep(0);

                amasar.start();
                preparar.start();
                hornear.start();
                finish.start();

                //ThreadAmasar.State.TERMINATED

                 System.out.println( pan.Nombre +  " A > " + amasar.getState());
                 System.out.println( pan.Nombre +  " P > " + preparar.getState());
                 System.out.println( pan.Nombre +  " H > " + hornear.getState());
                 System.out.println( pan.Nombre +  " F > " + finish.getState());


                System.out.println("Estableciendo tarea " + pan.Nombre);
                System.out.println("");
            } catch (InterruptedException ex) {
                Logger.getLogger(ThreadHacerPan.class.getName()).log(Level.SEVERE, null, ex);
                System.out.println(ex.getMessage());
            } catch (Exception ex) {
                System.out.println("Error interno:" + ex.getMessage());
            }
        }

先前的代码执行到线程“HacerPan”的“运行”方法,这个我的日志结果:

> Inicio: Thu Oct 11 11:27:53 CDT 2018
>>> Proceso iniciado:Thu Oct 11 11:27:53 CDT 2018
Pan 9 A > RUNNABLE
Pan 9 P > RUNNABLE
Pan 9 F > RUNNABLE
Pan 9 > Amasando... tiempo: 5000
Estableciendo tarea Pan 9

>>> Proceso iniciado:Thu Oct 11 11:27:53 CDT 2018
Pan 8 A > RUNNABLE
Pan 8 P > RUNNABLE
Pan 8 F > RUNNABLE
Estableciendo tarea Pan 8

>>> Proceso iniciado:Thu Oct 11 11:27:53 CDT 2018
Pan 8 > Amasando... tiempo: 30000
Pan 2 > Amasando... tiempo: 28000
Pan 2 A > TIMED_WAITING
Pan 2 P > RUNNABLE
Pan 2 F > RUNNABLE
Estableciendo tarea Pan 2 Pan 9 --> RUNNABLE
Pan 9 > Preparando...  tiempo: 13000
Pan 9 > Horneando... tiempo: 22000
Pan 2 --> RUNNABLE
Pan 2 > Preparando...  tiempo: 21000
Pan 8 --> RUNNABLE
Pan 8 > Preparando...  tiempo: 19000
Pan 9 cocinado!!!

如何捕获每个线程的“已终止”事件的正确方法?

很抱歉遗漏,线程“Amasar”,“Preparar”,“Hornear”和“Finish”的类代码是这样的:

public class ThreadHornear extends Thread {
    private Pan pan;
    private Thread parent;
    private ThreadCounter tc;

    public ThreadHornear (Pan pan, ThreadCounter tc){
        this.pan = pan;
        this.tc = tc;
    }

    public void SetParent(Thread parent){
        this.parent = parent;
    }

    @Override
    public void run(){
        try {
            if ( parent != null){
                parent.join();
            }
        } catch (InterruptedException ex) {
            Logger.getLogger(ThreadAmasar.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

这是“加入”线程的时候。

答案

您可以使用FutureFutureTask类来捕获“已终止”事件。以下代码是FutureTask的示例。

public class HowToCatchTerminatedEvent {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        FutureTask<Integer> futureTask = new FutureTask<>(() -> {
            System.out.println("run....");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        },1);
        Thread th = new Thread(futureTask);
        //NEW
        System.out.println(th.getState());
        th.start();
        //RUNNABLE
        System.out.println(th.getState());

        //blocked until the th thread done
        System.out.println(futureTask.get());
        //TERMINATED
        System.out.println(th.getState());
    }
}

以上是关于如何捕获Java连接线程中每个子进程的“已终止”事件的主要内容,如果未能解决你的问题,请参考以下文章

如何在ios中每n秒连续在后台线程中运行一个进程

进程-

如何创建线程?

Java并发编程:如何创建线程?

Java并发编程:如何创建线程?

Java并发编程:如何创建线程?