How're you attempting to stop them? Thread.stop
? Be warned that this method is deprecated.
Instead, look into using some sort of flag for thread 1 to communicate to thread 2 and 3 that they should stop. In fact, you could probably use interrupts.
Below, Thread.interrupt is used to implement the coordination.
final Thread subject1 = new Thread(new Runnable() {
public void run() {
while (!Thread.interrupted()) {
Thread.yield();
}
System.out.println("subject 1 stopped!");
}
});
final Thread subject2 = new Thread(new Runnable() {
public void run() {
while (!Thread.interrupted()) {
Thread.yield();
}
System.out.println("subject 2 stopped!");
}
});
final Thread coordinator = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(500);
} catch (InterruptedException ex) { }
System.out.println("coordinator stopping!");
subject1.interrupt();
subject2.interrupt();
}
});
subject1.start();
subject2.start();
coordinator.start();
Alternatively, you could also use a volatile boolean
(or AtomicBoolean) as means of communicating.
Atomic access provided by volatile
and java.util.concurrent.atomic.*
allow you to ensure mutation of the flag is seen by the subject threads.
final AtomicBoolean running = new AtomicBoolean(true);
final ExecutorService subjects = Executors.newFixedThreadPool(2);
subjects.submit(new Runnable() {
public void run() {
while (running.get()) {
Thread.yield();
}
System.out.println("subject 1 stopped!");
}
});
subjects.submit(new Runnable() {
public void run() {
while (running.get()) {
Thread.yield();
}
System.out.println("subject 2 stopped!");
}
});
final ScheduledExecutorService coordinator = Executors.newSingleThreadScheduledExecutor();
coordinator.schedule(new Runnable() {
public void run() {
System.out.println("coordinator stopping!");
running.set(false);
subjects.shutdown();
coordinator.shutdown();
}
}, 500, TimeUnit.MILLISECONDS);
Similarly, you could opt to, rather than use AtomicBoolean
, use a field such as:
static volatile boolean running = true;
Better yet, if you take advantage of ExecutorServices, you can also program similar code as follows:
final ExecutorService subjects = Executors.newFixedThreadPool(2);
subjects.submit(new Runnable() {
public void run() {
while (!Thread.interrupted()) {
Thread.yield();
}
System.out.println("subject 1 stopped!");
}
});
subjects.submit(new Runnable() {
public void run() {
while (!Thread.interrupted()) {
Thread.yield();
}
System.out.println("subject 2 stopped!");
}
});
final ScheduledExecutorService coordinator = Executors.newSingleThreadScheduledExecutor();
coordinator.schedule(new Runnable() {
public void run() {
System.out.println("coordinator stopping!");
subjects.shutdownNow();
coordinator.shutdown();
}
}, 500, TimeUnit.MILLISECONDS);
This takes advantage of the fact that ThreadPoolExecutor.shutdownNow interrupts its worker threads in an attempt to signal shutdown.
Running any example, the output should be something to the effect of:
C:devscrap>javac CoordinationTest.java
C:devscrap>java CoordinationTest
coordinator stopping!
subject 1 stopped!
subject 2 stopped!
Note the last two lines can come in either order.