如何在Java中停止线程?

时间:2009-10-23 07:27:10

标签: java multithreading

我用GUI创建了一个java程序,我想要一个停止按钮功能,当用户点击停止按钮时,必须停止该程序。

  1. 在我的程序中,主线程启动其他10个线程,我希望每当单击停止按钮时,必须在主线程之前停止所有10个线程。

  2. 其次,我还希望每当这10个线程的任何线程都停止时,它必须首先关闭它之前打开的所有资源,比如连接到数据库等。

  3. 我已经实现了代码........

    现在有一个问题。

    我的线程类是这样的:

    public class ParserThread implements Runnable {
        private volatile boolean stopped = false;
    
        public void stopTheThread() {
            stopped = true;
        }
        :
        :
    }
    

    以下是从函数start()

    启动10个线程的主线程
    public class Main() {
        Thread [] threads;
    
        public void start() {
            for(int i = 0; i < 10; i++) {
                threads[i] = new Thread(new ParserThread());
            }       
        }
    
        public void stop() {
            // code to stop all the threads
        }
    }
    

    现在我想调用ParserThread的stop方法来设置“stopped = true”来停止线程。我想要为所有10个线程完成这件事。

    如何调用stop方法。我希望它可以在Main类的stopAllThreads()方法中完成。

3 个答案:

答案 0 :(得分:8)

一般来说,这样做的方法是让每个其他线程定期检查一个标志。通常后台线程循环,等待工作 - 他们只需要在每次循环时检查标志。如果他们使用Object.wait()或类似的东西被告知有更多工作,则应该使用相同的通知来指示线程也应该停止。 (不要只是旋转直到你停止 - 这会吸收CPU。不要只是使用睡眠 - 这会延迟终止。)

允许所有线程干净地终止,适当地释放资源。 IMO,其他选项如interrupt()和已弃用的destroy()方法更难以正确控制。 (中断线程比硬中断更好,但它有一系列问题 - 例如中断只在某些点处理。)

编辑:在代码中,它看起来像:

// Client code
for (Task task : tasks) {
  task.stop();
}

// Threading code
public abstract class Task implements Runnable {

  private volatile boolean stopped = false;

  public void stop() {
    stopped = true;
  }

  protected boolean shouldStop() {
    return stopped;
  }

  public abstract void run();
}

然后,您的任务将继承Task。如果您希望stop()方法也通知监视器,则需要使其稍微复杂一些,但这是基本想法。

示例任务:

public class SomeTask extends Task {
  public void run() {
    while (!shouldStop()) {
      // Do work
    }
  }
}

答案 1 :(得分:0)

我不认为答案可以解决问题。这里是代码:

public class SomeTask extends Task {
   public void run() {
      while (!shouldStop()) {
        // Do work
      }
    }
  }

但如果&#34; Do work&#34;挂,不回来?在这种情况下,while无法检查标志。线程仍无法停止。

可能的解决方案可能是使用Process。

答案 2 :(得分:-1)

有一个控制器对象,其中有一个标志是否应该停止线程并且每个线程定期检查控制器并在单击停止按钮时退出(例如,如果要传输文件,则在接收/发送每个块之后) ,检查是否单击了停止。