【问题标题】:Use ExecutorService to control thread execution time使用ExecutorService控制线程执行时间
【发布时间】:2016-01-21 01:50:03
【问题描述】:

我是 Java 并发包的新手,想尝试 ExecutorService 来控制线程的执行时间。

所以对于一个保持运行的线程 MyThread,我想使用 ExecutorService 和 Future 类在 2 秒后停止它。

public class MyThread extends Thread {

    public static int count = 0;

    @Override
    public void run() {
        while (true) {
            System.out.println(count++);
        }
    }
}


public static void main(String[] args) throws IOException, InterruptedException {
    ExecutorService executorService = Executors.newFixedThreadPool(1);  
    MyThread thread = new MyThread();
    FutureTask<String> futureTask = new FutureTask<String>(thread, "success");
    try {
        executorService.submit(futureTask).get(2, TimeUnit.SECONDS);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (ExecutionException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (TimeoutException e) {
        System.out.println("timeout");
        e.printStackTrace();
        executorService.shutdownNow();
    }
}

但是,线程仍然在 2 秒后继续打印数字。如何在不改变 MyThread 类本身的情况下控制线程?

【问题讨论】:

  • 您已经编写了无限循环来打印数字。应该修改该类中的代码。
  • 我使用无限循环来查看ExecutorService是否可以停止线程。

标签: java java.util.concurrent


【解决方案1】:

使用ExecutorService 的主要目的是隐藏线程是如何为程序员创建、重用和管理的。

您需要实现Runnable,而不是创建MyThread

public class MyRunnable implements Runnable {
  private int count = 0;
  public void run() {
    while (true) {
      System.out.println(count++);
    }
  }
}

而且,这将是如何使用它:

Future<Void> f = executorService.submit(new MyRunnable());
f.get(2, TimeUnit.SECONDS);

关于问题中的终止属性,示例 Runnable 不是一个好的,因为它does not provide an interruptible task。例如,如果添加了sleep 操作:

public class MyRunnable implements Runnable {
  private int count = 0;
  public void run() {
    while (!Thread.currentThread().isInterrupted()) {
      System.out.println(count++);
      try {
        Thread.sleep(0, 1);
      } catch (InterruptedException x) {
        return;
      }
    }
  }
}

【讨论】:

  • 线程实现可运行。我也试过你的方法,Future f = executorService.submit(new MyRunnable()); f.get(2, TimeUnit.SECONDS);它仍然无法正常工作。线程一直在运行。
  • 也许了解一下差异是件好事:stackoverflow.com/questions/541487/…
  • 此外,您不能总是假设每个线程都是可中断的。您需要确保某些属性以允许线程被中断。这就是为什么你看到你解释的行为。阅读更多stackoverflow.com/questions/18702482/…
  • 其实我是用MyThread,把循环while(true)改成while(!Thread.currentThread().isInterrupted())。然后可以中断线程。我想除非有一个标签来检查线程是否中断,否则线程无法停止。谢谢@nobeh
【解决方案2】:

使用returnedFuture对象进行控制。

【讨论】:

    猜你喜欢
    • 2014-08-01
    • 2020-01-08
    • 2011-01-10
    • 1970-01-01
    • 1970-01-01
    • 2011-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多