【问题标题】:How to stop threads of a Java program?如何停止Java程序的线程?
【发布时间】:2010-12-06 10:56:19
【问题描述】:

我制作了一个带有 GUI 的 java 程序,并在其上放置了一个“停止”按钮。当我启动程序时,主线程启动了 10 个线程。现在我希望每当用户单击“停止”按钮时,所有线程都应该首先终止,然后主线程应该终止。我该怎么做。

【问题讨论】:

  • 我认为您需要为您的问题提供一些代码,因为这可能与您的线程初始化有关。

标签: java multithreading user-interface


【解决方案1】:

这取决于您希望 10 个线程如何“终止”,以及您如何运行线程。

我推荐creating an ExecutorService,并将您的“线程”编写为Runnable 实现。这些Runnable 对象应通过中止其任务、清理并尽快退出run 方法来响应其执行线程上对interrupt() 的调用。

Submit these Runnable tasksExecutorService 然后调用 awaitTermination,全部在主线程中。当用户按下“停止”按钮时,根据需要在ExecutorService(来自事件调度线程)上调用shutdownshutdownNow

如果你在执行器服务上调用shutdownNow,它会通过中断线程来通知正在运行的任务。如果您拨打shutdown,它将允许任务完成而不会中断。无论如何,您的主线程将阻塞awaitTermination,直到所有任务都完成(或时间限制用完)。

当然,您可以使用join 自己创建和管理所有线程。如果您希望能够过早停止线程,关键是使线程可中断。

【讨论】:

    【解决方案2】:

    首先,让我注意到Thread 类上有一个诱人的方法,叫做stop()不要使用,很危险

    这样做的一种方法是编写 10 个线程来检查线程的中断状态。

    例如

    while (! Thread.interrupted())
    {
         // Do your thread's work
    }
    

    您可以通过在Thread 对象上调用interrupt() 方法来中断每个工作线程,然后调用join() 以等待线程真正完成。

    【讨论】:

      【解决方案3】:

      给所有线程一个布尔值的共享实例,并让它们定期检查它是否为true。如果是true,线程应该从它的运行方法返回。如果用户按下停止按钮,则将此布尔值设置为true,然后使用Thread.join() 等待所有线程。

      【讨论】:

      • 如果在传统的 b=!b 中进行翻转会发生什么;方式和两个单独的线程会尝试翻转控制器布尔值? :) 当然可以解决,但不是我喜欢的解决方案。
      • 在问题中只有一个停止按钮来设置这个布尔值。没有危险。它只设置一次。
      • 你到底为什么要用 b=!b 翻转布尔值?它将是 terminate=true 或 running=false。任何=!只会让你发现一个错误。
      • 也就是说,顺便说一下,在每个线程上调用中断可能更有意义。
      • 这个中断不只是变相的布尔值吗?它仍然不是真正的中断,因为它在线程内部您需要检查线程是否被中断。
      【解决方案4】:

      Thread.stop() 已被弃用,建议您使用 Thread 定期检查的“正在运行”标志,以便当您将该标志设置为 false 时它可以自行终止。如果线程有很长的等待阶段,您可以中断()它以将其从等待()状态中唤醒。 -> Thread.stop() int he Java API doc

      通过将运行条件设置为 false 来终止您的线程后,您可以让您的主线程依次加入()其他线程以等待它们的终止。

      【讨论】:

        【解决方案5】:

        Thread 类上的suspend()resume() 方法已被弃用,因为它们本质上是不保存的。查看这篇文章,了解它们被弃用的原因以及停止线程的技术:

        http://java.sun.com/j2se/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html

        【讨论】:

          【解决方案6】:

          如果您的线程正在等待 InputStream,那么只需向线程添加一些布尔标志并关闭流。线程将唤醒,检查标志并退出。如果他们正在等待条件(Object.wait()),则相同,请使用 notifyAll() 并设置标志。如果您的线程不断循环(这是不好的),只需设置标志 :)

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-11-22
            • 2012-10-11
            • 2013-04-19
            • 2013-03-26
            相关资源
            最近更新 更多