简体   繁体   English

在使用java类启动线程列表之后,如何识别并重新启动已杀死的线程?

[英]How to identify and restart the threads that have been killed after starting a list of threads using the java class?

I have started 20 threads in my class, each thread will run in a loop to do something 我已经在课堂上启动了20个线程,每个线程都会循环运行以执行某些操作

for(int i=1;i<=20;i++) {
    MyThread mt = new MyThread(i);                  
    Thread t = new Thread(mt);
    t.start();
}

MyThread.java MyThread.java

public class MyThread implements Runnable{
    private int threadId;
    public MyThread(int i) {
        this.threadId = i;
    }
    @Override
    public void run() {
        if(threadId > 0) {
            while(1) {
                try {
                    //do something
                } catch(Exception ex) {
                    //do nothing
                }
            }
        }
    }
}

Now I want to monitor each thread and if anyone of them stops, I want to start a new thread with the corresponding threadId. 现在,我想监视每个线程,如果其中任何一个停止,我想使用相应的threadId启动一个新线程。 How can I do that? 我怎样才能做到这一点? Please help me. 请帮我。

I'll start with the possible states of the Thread class. 我将从Thread类的可能状态开始。 There are 6 possible states: 有6种可能的状态:

Enum Thread.State 枚举Thread.State

NEW : A thread that has not yet started is in this state. NEW:尚未启动的线程处于此状态。

RUNNABLE : A thread executing in the Java virtual machine is in this state. RUNNABLE:在Java虚拟机中执行的线程处于此状态。

BLOCKED : A thread that is blocked waiting for a monitor lock is in this state. BLOCKED:处于等待监视器锁定状态的被阻塞线程处于此状态。

WAITING : A thread that is waiting indefinitely for another thread to perform a particular action is in this state. 等待:无限期等待另一个线程执行特定操作的线程处于此状态。

TIMED_WAITING : A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state. TIMED_WAITING:此线程正在等待另一个线程执行操作的时间达到指定的等待时间。

TERMINATED : A thread that has exited is in this state. 终止:已退出的线程处于此状态。

Threads that "has been killed" as you said are those in Terminated state. 如您所说,“已被杀死”的线程处于“已终止”状态。 There are two main causes that will lead to the Terminated state. 有两个主要原因会导致终止状态。

  • A) The run() method exits normally after his work. A)run()方法在工作后正常退出。
  • B) Exception occurs and run() method ended. B)发生异常,并且run()方法结束。

If you want that your Threads "never" go in Terminated mode then you should A) have an infinite loop B) catch all exceptions. 如果您希望线程“永不”进入终止模式,则您应该A)有一个无限循环B)捕获所有异常。 But that was not exactly your question. 但这不完全是您的问题。 How to monitor the state of the Threads? 如何监视线程​​的状态?

Key is the getState() method 关键是getState()方法

public Thread.State getState() 公共Thread.State getState()

Returns the state of this thread. 返回此线程的状态。 This method is designed for use in monitoring of the system state, not for synchronization control. 此方法设计用于监视系统状态,而不用于同步控制。

You can do what you want with the following 3 classes: 您可以使用以下3个类来做您想做的事情:

App.java App.java

package com.what.ever;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class App {

    private static int MONITORING_FREQUENCY = 5;
    private static int NUMBER_OF_TASKS = 3;

    public static void main(String[] args) {
        List<ThreadMonitor> threadMonitors = initThreadMonitors();

        threadMonitors.forEach(m -> m.printState());
        threadMonitors.forEach(m -> m.startThread());

        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
        scheduler.scheduleAtFixedRate(() -> threadMonitors.forEach(m -> m.restartIfTerminated()), MONITORING_FREQUENCY, MONITORING_FREQUENCY, TimeUnit.SECONDS);
    }

    private static List<ThreadMonitor> initThreadMonitors() {
        List<ThreadMonitor> threadMonitors = new ArrayList<>();

        for (int i = 1; i <= NUMBER_OF_TASKS; i++) {
            DummyRunnable runnable = new DummyRunnable(i);
            ThreadMonitor threadMonitor = new ThreadMonitor(runnable);
            threadMonitors.add(threadMonitor);
        }

        return threadMonitors;
    }
}

ThreadMonitor.java ThreadMonitor.java

package com.what.ever;

public class ThreadMonitor {

    private Thread thread;
    private DummyRunnable runnable;

    public ThreadMonitor( DummyRunnable runnable) {
        this.runnable = runnable;
        this.thread = new Thread(runnable);
    }

    public boolean startThread() {
        boolean isStarCalled = false;
        if(Thread.State.NEW.equals(thread.getState())) {
            thread.start();
            isStarCalled = true;
        }
        return isStarCalled;
    }

    public void printState() {
        System.out.println( thread.toString() + " is in state : " + thread.getState());
    }

    public void restartIfTerminated() {
        printState();
        if(Thread.State.TERMINATED.equals(thread.getState())) {
            thread = new Thread(runnable);
            thread.start();
        }
    }
}

DummyRunnable.java DummyRunnable.java

package com.what.ever;

public class DummyRunnable implements Runnable {

    private int id;

    public DummyRunnable(int id) {
        this.id = id;
    }

    public void run() {
        System.out.println("Runnable " + id + " started in thread: " + Thread.currentThread());
        dummyWork();
        System.out.println("Runnable " + id + " done");
    }

    private void dummyWork() {
        int sleep = 10000;
        if (id == 3) {
            sleep = 1000;
        }
        try {
            Thread.sleep(sleep);
        } catch (Exception e) {
            System.out.print(e);
        }
    }
}

Here you go. 干得好。 If you have any question about this example, just ask. 如果您对此示例有任何疑问,请询问。

Small warnings: Be careful with the monitoring frequency, it can have huge impact on the performances. 小警告:请注意监视频率,它可能会对性能产生巨大影响。 Don't try to do real time application with this. 请勿尝试对此进行实时应用。

If you want to test threads then keep a list of threads in an array: 如果要测试线程,则将线程列表保留在数组中:

MyThread[] mt = new MyThread[20];
...
mt[i] = ...

Now you can inquire on each thread with methods from the Thread Class, for instance: isAlive(); 现在,您可以使用Thread类中的方法查询每个线程,例如:isAlive();。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM