优雅地关闭具有无限while循环的多个线程的程序

时间:2013-05-05 18:33:58

标签: java multithreading shutdown

我有一个程序可以创建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
                }
            }   
    }
}

任何帮助都将得到真正的赞赏。

3 个答案:

答案 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 ......保持简单......

  1. 使静态stop变量易变 ......

  2. 然后将此方法添加到SampleGSH ...

    public void shutdown() { stop = true; }

  3. 然后在您想要停止线程时调用它!

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