【问题标题】:Stop a runnable in a separate Thread在单独的线程中停止可运行对象
【发布时间】:2012-12-07 04:22:35
【问题描述】:

嘿,我目前的 Android 应用程序有问题。我正在通过 实现 Executor 接口:

class Flasher implements Executor {
    Thread t;
   public void execute(Runnable r) {
     t = new Thread(r){
     };
     t.start();
   }
 }

我这样启动我的 Runnable:

flasherThread.execute(flashRunnable);

但我怎样才能阻止它呢?

【问题讨论】:

  • 不要在没有充分理由的情况下实现您自己的Executor - 使用Java API 中已经可用的那些。此外:在 Java 中停止在另一个线程中执行的任务总是依赖于另一个线程,或者更确切地说是它的任务来合作。如果您的Runnable 一直处于无限循环中,基本上什么都不做,那么就没有办法阻止它。
  • @ρяσѕρєяK Executor接口中没有这种方法。

标签: java android multithreading runnable


【解决方案1】:

不确定实施Executor 是个好主意。我宁愿使用 Java 提供的执行器之一。它们允许您通过Future 接口控制您的Runnable 实例:

ExecutorService executorService = Executors.newSingleThreadExecutor();
Future<?> future = executorService.submit(flashRunnable);
...
future.cancel(true);

当您的程序不再需要异步执行时,通过调用executorService.shutdown() 来确保释放ExecutorService 正在消耗的资源。

【讨论】:

  • "允许你控制你的 Runnable 实例" - 抱歉,这不是真的。它们允许你控制 Executor,但Runnable 仍然可以做任何它喜欢的事情,包括不终止并因此搞砸执行器等等。
  • future.cancel() 方法可能返回 false,表示您的取消请求已失败,但 Future 控制单个 Runnable 实例,而不是可能执行或调度数千个任务的 Executor /跨度>
  • 那么,如何通过Future 影响Runnable 实例?
  • Runnable 的线程将被“中断” - 但这并不一定意味着将抛出 InterruptedException,或者对 Runnable 实例有任何其他影响.因此,如果 Runnable 没有明确准备处理外部设置的终止条件,则有 "no" 方法来阻止它。
  • 我并没有说它是有保证的。您仍然可以使用 Thread.interrupted() 调用来检查是否调用了 interrupt() 而不是编写老式代码的音调
【解决方案2】:

您应该查看ExecutorService,而不是实现自己的Executor。 ExecutorService 有一个关闭方法:

启动有序关闭,执行之前提交的任务,但不会接受新任务。

【讨论】:

    【解决方案3】:

    好的,这只是非常基本的线程 101,但让我们再举一个例子:

    老式线程:

    class MyTask implements Runnable {
        public volatile boolean doTerminate;
    
        public void run() {
            while ( ! doTerminate ) {
                // do some work, like:
                on();
                Thread.sleep(1000);
                off();
                Thread.sleep(1000);
            }
        }
    }
    

    然后

    MyTask task = new MyTask();
    
    Thread thread = new Thread( task );
    
    thread.start();
    
    // let task run for a while...
    
    task.doTerminate = true;
    
    // wait for task/thread to terminate:
    thread.join();
    // task and thread finished executing
    

    编辑:

    刚刚偶然发现了这个非常有用的 Article 关于如何停止线程的信息。

    【讨论】:

    • Java 中断线程的标准方式是……中断线程。在您的 Runnable 中,您可以使用 while(!Thread.currentThread().isInterrupted()) {soSomething();} 在发送中断信号时停止您正在执行的操作。
    • 毫无疑问。 - 但是,仍然没有 方法可以强制任意的Runnable(或线程)终止;在每个案例中,Runnable 的合作都是必需的。这就是 OP 的重点:为了能够停止正在运行的线程,必须显式编写该线程中的代码以支持它。
    • 我不是在争论合作位 - 只是说合作通常是通过中断机制而不是布尔标志来实现的。
    【解决方案4】:

    我建议使用 ExecutorService 和 Furure 对象,它可以让您控制正在由执行程序创建的线程。像下面的例子

    ExecutorService executor = Executors.newSingleThreadExecutor();
    Future future = executor.submit(runnabale);
    try {
         future.get(2, TimeUnit.SECONDS);
    } catch (TimeoutException ex) {
         Log.warn("Time out expired");
    } finally {
         if(!future.isDone()&&(!future.isCancelled())) 
            future.cancel(true);
    
        executor.shutdownNow();
    }
    

    这段代码说runnable将在2秒后被强制终止。当然,您可以随意处理您的 Future 对象,并根据您的要求终止它

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-06
      • 1970-01-01
      • 1970-01-01
      • 2013-10-06
      • 2013-09-26
      • 2019-08-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多