我有一个程序可以创建10个线程,每个线程都有一个无限运行的while循环。 我需要帮助来有效地实现一个可以有效地停止所有线程的Shutdown钩子。由于我想做一个正常的关闭,每个Thread一旦发现stop标志变为TRUE就应该完成。
public class SampleGSH implements Runnable{
private static boolean stop = false;
public static void main(String[] args) {
for(int i = 0; i < 10;i++) {
Thread t = new Thread(new SampleGSH(), "name"+i);
t.start();
}
}
@Override
public void run() {
Runtime.getRuntime().addShutdownHook(new Thread("shutdown thread") {
public void run()
{
System.out.println("*******");
synchronized (this)
{
System.out.println("Turning switch off");
stop = true;
}
}
});
synchronized (this) {
while(!stop)
{
//Some logic which should not be killed abruptly once it starts running, a graceful shut down will not allow this code to start
}
}
}
}
任何帮助都将得到真正的赞赏。
答案 0 :(得分:2)
这是常见问题解答。如果您有多个线程共享的任何字段,则需要同步它们。在这种情况下,您的stop
应为volatile
。如果没有这个,没有任何东西可以确保线程看到stop
的值变为true
。有关原子访问的信息,请参阅this tutorial。
请参阅:Using boolean var for stopping threads
结合其他评论:
ExecutorService
while
循环位于synchronized
块内。这没有任何作用,stop
字段不会获得内存同步,因为它在块内部进行外部更新。停止线程的另一种方法是interrupt()
它。请参阅this tutorial。
while (!thread.currentThread().isInterrupted()) {
...
}
...
t.interrupt();
答案 1 :(得分:1)
忘记addShutdownHook
guff ......保持简单......
使静态stop
变量易变 ......
然后将此方法添加到SampleGSH ...
public void shutdown() {
stop = true;
}
然后在您想要停止线程时调用它!
答案 2 :(得分:0)
而不是单个静态停止布尔值,您可以为每个线程提供自己的停止布尔值。然后在创建它们时存储所有线程对象,并在关闭钩子线程中将它们的stop boolean设置为true(将挂钩在main方法中)。
这样的事情:
import java.util.ArrayList;
import java.util.List;
public class SampleGSH extends Thread {
public boolean stop = false;
private static List<SampleGSH> threads = null;
public static void main(String[] args) {
threads = new ArrayList<SampleGSH>();
int numThreads = 10;
for (int i = 0; i < numThreads; i++) {
SampleGSH t = new SampleGSH();
threads.add(t);
t.start();
}
Runtime.getRuntime().addShutdownHook(new Thread("shutdown thread") {
public void run() {
System.out.println("*******");
for (SampleGSH t : threads) {
t.stop = true;
}
}
});
}
@Override
public void run() {
{
while (!stop) {
// Some logic which should not be killed abruptly once it starts
// running, a graceful shut down will not allow this code to
// start
}
}
}
}