【问题标题】:How to stop threads in Java?如何停止Java中的线程?
【发布时间】:2015-05-27 12:44:06
【问题描述】:

我制作了一个带有 GUI 的 java 程序,我想要一个停止按钮功能,当用户单击停止按钮时,程序必须停止。

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

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

我已经实现了........所回答的代码

现在有一个问题。

我的线程类是这样的:

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 个线程完成此操作。

如何调用该停止方法。我希望它在 Main 类的 stopAllThreads() 方法中完成。

【问题讨论】:

标签: java multithreading


【解决方案1】:

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

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

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

// 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
    }
  }
}

【讨论】:

  • 你能用程序解释一下吗?如何在我的程序中实现它。你可以在stackoverflow.com/questions/1611822/…查看我的程序的一部分@
  • “定期检查标志”也称为“主动等待”,不推荐。使用等待/通知来避免这种情况。
  • @pimpf0r:如果您要旋转或睡眠,您只需要使用等待/通知。如果你有一个稳定的工作流,那很好。请注意,如果您想睡觉,我已经在答案中提到了使用 wait() 。
  • 我认为打断在这里更可取。唯一真正的缺点是 isInterrupted() 在您收到 InterruptException 后返回 false,但只要您知道您几乎可以将其视为内置的相同模式。
  • @Fredrik:我真的不喜欢中断......我相信以保持一致状态的方式编写工作线程变得更加困难。如果您在代码中严格控制退出点,则可以确保您非常容易地保持一致。
【解决方案2】:

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

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

但是如果“Do work”挂起不返回怎么办?在这种情况下,while 不能检查标志。线程仍然无法停止。

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

    • 迟到且与之前的答案几乎相同。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-06
    • 2017-01-06
    • 2015-12-04
    • 2013-11-22
    • 2012-10-11
    • 1970-01-01
    相关资源
    最近更新 更多