2013-05-05 74 views
1

我有一个创建10个线程的程序,每个线程都有一个无限循环while循环。 我需要帮助来有效地实现一个关闭挂钩,它可以有效地停止所有的线程。因为我想做一个正常的关闭,所以每当一个线程发现停止标志变为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 
       } 
      } 
    } 
} 

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

回答

2

这是一个常见问题解答。如果您有多个线程共享的字段,则需要对其进行同步。在这种情况下,您的stop应该是volatile。没有这个,没有任何东西可以确保线程将stop的值更改为true。有关原子访问的信息,请参阅this tutorial

参见:Using boolean var for stopping threads

情侣其他意见:

  • 如果要启动多个线程,你应该考虑使用ExecutorService
  • while循环是一个​​块内。这样做什么也不做,stop字段将不会获得内存同步,因为它在块内部进行外部更新。
  • 停止线程的另一种方法是对interrupt()它。请参阅this tutorial

    while (!thread.currentThread().isInterrupted()) { 
        ... 
    } 
    ... 
    t.interrupt(); 
    
0

而不是一个单一的静态停止布尔,你可以给每个线程它自己停止布尔值。然后在创建它们时存储所有线程对象,并在关闭钩子线程(将挂钩在主方法中)中将其停止布尔值设置为true。

事情是这样的:

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

或者只是使用thread.interrupt()和thread.isInterrupted()方法,而不是@Gray的建议。 – 2013-05-05 19:00:51

1

忘了说addShutdownHook废话...保持它的简单...

  1. 使静态stop变量挥发性 ...

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

    public void shutdown() { stop = true; }

  3. 然后调用它,当你想停止线程!