首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java Executors:如何停止提交的任务?

Java Executors:如何停止提交的任务?
EN

Stack Overflow用户
提问于 2009-09-13 15:41:05
回答 5查看 32.6K关注 0票数 17

我已经使用executors提交了一个任务,我需要它在一段时间(例如5分钟)后停止。我试过这样做:

代码语言:javascript
复制
   for (Future<?> fut : e.invokeAll(tasks, 300, TimeUnit.SECONDS)) {
         try {
             fut.get(); 
         } catch (CancellationException ex) {
             fut.cancel(true);   
             tasks.clear();
         } catch(ExecutionException ex){
             ex.printStackTrace(); //FIXME: gestita con printstack       
         }
   }

但我总是得到一个错误:我有一个共享的Vector,需要由任务修改,然后由线程读取,即使我停止了所有任务,如果发生超时,我也会得到:

代码语言:javascript
复制
Exception in thread "Thread-1" java.util.ConcurrentModificationException

有什么问题吗?如何停止5分钟后仍在工作的已提交任务?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2009-09-13 16:57:14

仅仅因为您在Future上调用cancel()并不意味着任务将自动停止。您必须在任务中做一些工作,以确保它将停止:

  • 使用cancel(true)以便向任务发送中断。
  • 处理InterruptedException。如果任务中的某个函数抛出了computation.

,请确保在任务连续执行InterruptedException时捕获到exception.

  • Periodically check Thread.currentThread().isInterrupted()后尽快正常退出

例如:

代码语言:javascript
复制
class LongTask implements Callable<Double> {
    public Double call() {
        
         // Sleep for a while; handle InterruptedException appropriately
         try {
             Thread.sleep(10000);
         } catch (InterruptedException ex) {
             System.out.println("Exiting gracefully!");
             return null;
         }


         // Compute for a while; check Thread.isInterrupted() periodically
         double sum = 0.0;
         for (long i = 0; i < 10000000; i++) {
             sum += 10.0
             if (Thread.currentThread().isInterrupted()) {
                 System.out.println("Exiting gracefully");
                 return null;
             }
         }

         return sum;
    } 
}

此外,正如其他帖子所提到的:即使使用线程安全的Vector类,也可能抛出ConcurrentModificationException,因为从Vector获得的迭代器不是线程安全的,因此需要同步。增强的for循环使用迭代器,所以要小心:

代码语言:javascript
复制
final Vector<Double> vector = new Vector<Double>();
vector.add(1.0);
vector.add(2.0);

// Not thread safe!  If another thread modifies "vector" during the loop, then
// a ConcurrentModificationException will be thrown.
for (Double num : vector) {
    System.out.println(num);
}

// You can try this as a quick fix, but it might not be what you want:
synchronized (vector) {    // "vector" must be final
    for (Double num : vector) {
        System.out.println(num);
    }
}
票数 29
EN

Stack Overflow用户

发布于 2009-09-13 16:15:56

ConcurrentModificationException来自您对tasks.clear()的调用,而您的Exceutors正在迭代您的tasks Vector。您可以尝试在ExecutorService上调用shutdownNow()

票数 1
EN

Stack Overflow用户

发布于 2009-09-13 15:57:28

对于ConcurrentModificationException来说,最常见的情况是在迭代的同时修改vector。通常,这将在单个线程中完成。在整个迭代过程中,您需要在Vector上持有一个锁(注意不要死锁)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1418033

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档