【问题标题】:Killing a thread invoked asynchronously using executor service使用执行器服务杀死异步调用的线程
【发布时间】:2018-07-24 00:22:45
【问题描述】:

我正在尝试为执行程序异步调用的线程实现超时。

流程如下:

线程 1: 使用下面的代码启动任务以在线程 2 上运行并立即返回,而无需等待 Future 对象结果

线程 2: 漫长的过程,并会更新一些存储,一些结果在最后缓存中

现在,要求是在某个超时值后杀死 Thread-2 而不会阻塞 Thread-1

代码 sn-p:

    ExecutorService executor = Executors.newFixedThreadPool(1);
    Future<Task> future = executor.submit(new Callable<Task>() {

        public Task call() throws Exception {
            try{

            return new Task();
            }catch (Exception e) {
            //print stack
        }

        }
    });

有什么见解/建议来实现这个吗?

【问题讨论】:

  • 您需要注意一些事情。 1. 你有多少生产者线程和消费者线程。 2、其实thread2不能杀,除非它处于等待状态。
  • 我认为这不是一个好主意。

标签: java multithreading timeout executorservice


【解决方案1】:

查看以下答案:https://stackoverflow.com/a/2733370/1299078

但是根据 Thread-2 所做的事情,您可以让线程定期结束,即在 http-request 或 DB 语句上定义超时,或者如果您有循环,则定义退出条件。这样,您最终可能会得到更合适的解决方案,并且能够正确释放资源。

【讨论】:

  • 如果我们在该 URL 中使用解决方案,Thread-1 将被阻止。根据我的要求,它不应该
  • 分叉你的电话是绝对可以的。我的观点是,您可以在分叉的任务中指定超时。这样超时会在 Thread-2 中被击中,并且会在不阻塞 Thread-1 的情况下终止 Thread-2,并且您不必主动杀死 Thread-2。
【解决方案2】:

您不能使用 Java 的 ExecutorService 来执行此操作,因为它不会将任何方法暴露给超时并杀死/完成/完成新生成的线程。

但是,如果你必须这样做,那么你可以直接使用 Thread 类来完成,下面是高级方法:

  • 从您的主线程 t1 生成您的工作线程 t2,它应该可以完成您的长期工作。
  • 在您的 t1 中,您将持有 t2 的 ORV,将新线程 t3 连同您希望 t2 完成的时间一起传递给它。
  • 在 t3 中(如果您愿意,您也可以在 t1 中执行此操作,但由于您不希望阻塞 t1,因此您需要有另一个线程来执行此工作),一旦该时间过去,请调用 t2.interrupt(),这基本上会打断t2线程。
  • 现在在 t2 中,您将不得不定期继续检查线程是否被中断(使用 if (Thread.interrupted()) {),如果它被中断,那么您可以做任何您想做的事情 - 只需返回因此完成/杀死/完成线程。

【讨论】:

    【解决方案3】:

    基本的 ExecutorService 不提供超时功能。

    您可以像@hagrawal 描述的那样自己实现超时,或者您可以使用番石榴,它对您所要求的here 有一个非常好的实现@

    【讨论】:

      猜你喜欢
      • 2021-03-12
      • 2019-10-12
      • 2017-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多