【问题标题】:Interrupting a Runnable with a method of the class使用类的方法中断 Runnable
【发布时间】:2013-09-15 15:04:10
【问题描述】:

如何编写实现Runnable 接口(从ExecutorService 开始)的类的方法来中断线程?

我知道我可以使用Future fut = es.submit(foo);(其中esExecutorServicefoo 是我的类的一个实例)然后从应用程序的主函数内部调用fut.cancel(true);,但是如何我应该从类本身内部调用类似的东西吗?

我想在我的 Runnable 类中有一个方法

public void stop() {…}

这样我就可以从任何地方(包括从应用程序的主函数)调用foo.stop(),它就像我使用了Future.cancel 函数一样工作(如果线程正在等待,它必须引发 ÌnterruptedException`获取信号量)。

【问题讨论】:

    标签: java multithreading java.util.concurrent


    【解决方案1】:
                public class MyRunnable implements Runnable {
    
                    private Thread currentThread;
    
                    @Override
                    public void run() {
                        currentThread = Thread.currentThread();
                        // Do here something interruptible
                    }
    
                    public void interrupt() {
                        if (currentThread != null)
                            currentThread.interrupt();
                    }
                }
    

    但正如人们所说,这是一个糟糕的架构,因为您将正在做什么(可运行)与如何完成(执行)的职责混合在一起

    【讨论】:

      【解决方案2】:

      您可以创建自己的类来实现Runnable 以及另一个接口:

      public interface StoppableRunnable extends Runnable {
          public void stop();
      }
      

      并使用这种类型的Runnable,它保证有一个可以调用的stop() 方法。

      使用示例:

      public MyRunnable implements StoppableRunnable {
      
          private volatile boolean stopped = false;
      
          public void run() {
             while(!stopped) { // Do something.... }
          }
      
          public void stop() {
              stopped = true;
          }
      }
      

      【讨论】:

      • 这似乎不能解决我的问题,因为它不会向 Runnable 发送中断。在我的主循环中,线程大多停留在信号量上等待,所以我需要 stop 方法让它停止等待并引发异常,以便回到循环的开头并看到它已经停止。跨度>
      【解决方案3】:

      你想要做的——在Runnable 中实现stop() 方法——实际上可能会给你的代码结构带来一些混乱。为什么? Runnable 对象在设计上是包含必须运行的代码的东西。但是添加stop() 方法将超出Runnable 对象的唯一责任:也就是说,您将使其能够控制代码的执行。应该避免这种情况。

      这里有个提示:Runnable 中没有 start() 方法。事实上,Thread 类中有一个,并且在 JDK 中引入了Runnable 接口以减少“可运行”代码与控制其执行的对象(实例Thread)。

      我的问题是:为什么您对future.cancel() 不满意?您能否在您的设计要求中添加一些精度?

      【讨论】:

      • 我理解你的解释,为什么让 Runnable 自行停止是不好的。我更喜欢使用 Runnable 并从 ExecutorService 启动它,因为这样我就有了从同一个对象启动的线程,并且 ExecutorService 可以在需要时关闭它们(并且还控制同时启动的此类线程的数量) .我最终编写了一个停止方法,该方法从主类作为参数传递了 Future。它起作用了,或多或少是我想要的,但它可能不是对 Runnables 的正确使用。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-04
      相关资源
      最近更新 更多