如何识别并重新启动使用java类启动线程列表后已被终止的线程?

问题描述:

我已经在我的课开始了20个线程,每个线程将运行在一个循环中做一些事情如何识别并重新启动使用java类启动线程列表后已被终止的线程?

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

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 
       } 
      } 
     } 
    } 
} 

现在我要监控每个线程,如果他们中的任何人停止,我想用相应的threadId启动一个新的线程。我怎样才能做到这一点?请帮帮我。

+1

如何确保线程不停止? '尝试'''catch'抛出的任何'Exception'。 –

+0

本文使用自定义侦听器在线程停止时得到通知:http://www.algosome.com/articles/knowing-when-threads-stop.html – Berger

+0

@Andy Turner Java代码异常是线程可以停止的唯一方法吗?我们可以监视线程并检查它们中的任何一个是否存在于主类中? – user3608212

如果你想测试线程然后继续线程的列表中的数组:

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

现在你可以从Thread类方法的每个线程上查询,例如:的IsAlive();

我将从Thread类的可能状态开始。有6种可能的状态:

Enum Thread.State

新:还没有开始就处于这种状态的线程。

RUNNABLE:在Java虚拟机中执行的线程处于此 状态。

BLOCKED:阻塞等待显示器锁定的线程处于 此状态。

WAITING:等待无限期地等待另一个线程执行特定动作的线程处于此状态。

TIMED_WAITING:正在等待另一个线程执行的线程 对于达到指定等待时间的操作处于此状态。

TERMINATED:退出的线程处于此状态。

正如你所说的那样“已被杀死”的线程是处于终止状态的线程。有两个主要原因会导致终止状态。

  • A)run()方法在他的工作后正常退出。
  • B)发生异常,run()方法结束。

如果你想让你的线程“永不”进入终止模式,那么你应该A)有一个无限循环B)捕获所有异常。但那不完全是你的问题。如何监视线程​​的状态?

主要是getState()方法

公共Thread.State的getState()

返回该线程的状态。此方法设计用于监视系统状态,而不是用于同步控制。

你可以做你想做的有以下3类:

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

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

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); 
     } 
    } 
} 

在这里,你去。如果您对这个例子有任何疑问,只需询问。

小警告: 小心监控频率,会对性能产生巨大影响。不要试图用这个做实时应用。