我已经使用执行器提交了一个任务,我需要它在一段时间后停止(例如5分钟).我试过这样做:
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需要被任务修改,然后被一个线程读取,即使我停止了所有的任务,如果超时发生我得到:
Exception in thread "Thread-1" java.util.ConcurrentModificationException
有什么不对? 5分钟后如何停止提交的工作?
解决方法
只是因为你在Future上调用cancel()并不意味着任务会自动停止.你必须在任务中做一些工作,以确保它停止:
>使用cancel(true),以便将中断发送到任务.
>处理InterruptedException.如果您的任务中的函数抛出InterruptedException,请确保在捕获异常时尽快退出.
>如果任务执行连续计算,请定期检查Thread.currentThread().isInterrupted().
例如:
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循环使用迭代器,因此请注意:
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); } }