【问题标题】:How to stop a thread - Java如何停止线程 - Java
【发布时间】:2014-03-26 08:54:18
【问题描述】:

如果我有以下结构,有人可以告诉我如何停止线程吗?

我想在线程C过期后停止线程B

    c = new c();
    c.start();
    b = new b();
    b.start();

class c extends Thread {

    @Override
    public void run() {
      // DRAW IMAGE
      // b.stop(); - doenst work
    }
}

class b extends Thread {

    @Override
    public void run() {
      // PROGRESS BAR

    }
}

【问题讨论】:

  • 您应该使用 Swing Timer(甚至是常规的 java.util.Timer)来实现进度条,然后您就不必求助于任何技巧来停止。

标签: java multithreading


【解决方案1】:

没有立即停止线程的好方法。

  • Thread.stop(),但它很危险且已弃用。除非您彻底分析了您的代码并确定风险是可以接受的,否则不要使用它。

  • Thread.interrupt(),但不保证线程会很快停止,甚至完全停止。

例如:

while (!Thread.interrupted()) {
    try {
        //do stuff
    } catch (InterruptedException e) {
        // end up
    }
}
  • 有编写线程定期检查标志的方法,但如果不经常检查标志(意外或设计),则线程不会快速停止。

详情请咨询this

【讨论】:

  • 这是一个相当悲观的答案。 OP 似乎可以完全控制每个线程的代码,因此您的第二个或第三个要点是解决此问题的完美实用解决方案。
  • 您应该展示如何使用Thread.currentThread().isInterrupted() 的代码示例。是的,您可能不会检查它。此外,还有守护线程。
【解决方案2】:

不要使用.stop() 而是使用interrupt()

你需要定期检查你的b线程是否被中断,如果被中断,你可以采取适当的措施-

if(b.isInterrupted()){
  //end your work
}

--->http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html

【讨论】:

    【解决方案3】:

    不要使用 Thread.stop() 方法,它已经被弃用了,在这种情况下你可以在你的代码中处理 b 线程的停止。

    例如:

    class b extends Thread {
        private volatile boolean stopped = false;
    
    
        public void stop () {
            stopped = true;
        }
    
        @Override
        public void run() {
          // PROGRESS BAR
          while ( ! stopped ) {
             // paint the progress bar
          }
    
        }
    }
    

    【讨论】:

      【解决方案4】:

      您可能想看看this。你可以使用一个标志或者只使用Thread.currentThread().interrupt(),你可以通过调用Thread.isInterrupted()来检查线程是否被中断。

      【讨论】:

        【解决方案5】:

        here 很好地解释了这个问题的解决方案。任何可能需要关闭状态标志的线程都可以具有以下结构:

        volatile boolean shutdownRequested;
        
        ...
        
        public void shutdown() { shutdownRequested = true; }
        
        public void doWork() { 
            while (!shutdownRequested) { 
                // do stuff
            }
        }
        

        因此,在您的情况下,您的 B 类看起来与上述类似。然后在C类中,可以调用B类的shutdown()方法。

        【讨论】:

          【解决方案6】:

          在您的调用代码中创建一个可锁定的对象

          Boolean canRun = true;
          c = new c();
          

          b 完成后将canRun 设置为false

          定期检查canRunc 中的值

          【讨论】:

            【解决方案7】:

            好吧,试试这个:

            while(true) {
              if (!c.isAlive() && b.isAlive()){
                  b.interrupt();
              }
            }
            

            【讨论】:

              【解决方案8】:

              试试类似的东西

               private void startActionPerformed(java.awt.event.ActionEvent evt) {
              
               p=new Progress();
               myThread=new Thread(p);
               p.setLocationRelativeTo(null);
               p.setVisible(true);
               myThread.start();
              
              }
              
              private void stopActionPerformed(java.awt.event.ActionEvent evt) {
              
                if(myThread!=null){
                p.Terminate();
                try {
                myThread.join();
                } catch (InterruptedException ex) {
               Logger.getLogger(ClassA.class.getName()).log(Level.SEVERE, null, ex);
                 }
                 }
              
                 }
              

              /////////////////////////////////////// ////////////////

              它是如何工作和停止的!

                  int i;
                  volatile boolean running=true;
                  public void run(){
                        while(running){
                    for(i=0;i<=100;i++){
                  pro.setValue(i);
                   try {
                   Thread.sleep(200);
                   } catch (InterruptedException ex) {
                   Logger.getLogger(Progress.class.getName()).log(Level.SEVERE, null, ex);
                  return;
                  }
                 if(i==100){
                   Terminate();
                  break;
                  }
                 }
               }
              
              }
              

              公共无效终止(){ 运行=假; }

              /////////////////////////////////////// ///////////////////////p>

              【讨论】:

                【解决方案9】:

                使用Boolean 标志。

                为了线程安全,请使用AtomicBoolean

                AtomicBoolean running = new AtomicBoolean(Boolean.TRUE);
                

                在您的 run() 方法中,在一段时间内检查此标志:

                public void run(){
                    while(running){
                    ...
                    }
                }
                

                当您想停止此Thread 时,请将running 更改为false

                【讨论】:

                • AtomicBoolean 太过分了,volatile boolean 就足够了。还有平台提供的interrupted标志。
                • 这有什么过分的?它只是对象内部的一个 volatile 变量。这听起来对我来说是微优化。
                • 解释 volatile 变量有什么问题。如果你不能,那就太矫枉过正了。抛出诸如“微优化”之类的词来证明无端的过度复杂化只不过是承认你的论点的弱点。
                • volatile boolean 更简单,它是本地语言功能,不需要方法调用来设置或获取它,它会自动初始化。但所有这些都是如此明显,以至于它们真的不需要解释。 AtomicBoolean 是针对您不打算使用的原子 CAS 操作的特定用例引入的。
                • 先生,这越来越主观了。你更喜欢原语,我不喜欢,而且使用包装器从来没有任何性能问题。实际上,我认为非基元使代码更清晰(可能我已经习惯了)。而且我认为不应该用可读性来换取微优化。但我再次说过,这取决于应用程序的需求。如果您开发的应用程序硬件有限且必须具备高性能,那么这是有道理的。但我听说人们也使用 C!本次讨论结束。
                猜你喜欢
                • 1970-01-01
                • 2010-12-06
                • 2013-11-22
                • 2012-10-11
                • 1970-01-01
                • 1970-01-01
                • 2011-03-12
                • 2013-04-19
                相关资源
                最近更新 更多