Reputation: 31
I have started 20 threads in my class, each thread will run in a loop to do something
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
}
}
}
}
}
Now I want to monitor each thread and if anyone of them stops, I want to start a new thread with the corresponding threadId. How can I do that? Please help me.
Upvotes: 1
Views: 146
Reputation: 803
I'll start with the possible states of the Thread class. There are 6 possible states:
NEW : A thread that has not yet started is in this state.
RUNNABLE : A thread executing in the Java virtual machine is in this state.
BLOCKED : A thread that is blocked waiting for a monitor lock is in this state.
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.
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.
If you want that your Threads "never" go in Terminated mode then you should A) have an infinite loop B) catch all exceptions. But that was not exactly your question. How to monitor the state of the Threads?
Key is the getState() method
public 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:
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);
}
}
}
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.
Upvotes: 2
Reputation: 1904
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();
Upvotes: 0