【发布时间】:2014-04-08 23:39:48
【问题描述】:
我在 SO 上问了一个问题 here 并得到了解决方案 there。但是在运行该解决方案之后,它似乎无法按预期工作。
换句话说,我正在遍历一堆 Java 文件并逐个分析它们。我的分析算法可能需要 1 秒到 5-10 小时,可能。但如果分析在 10 分钟内还没有完成,我想完成分析。程序长时间运行也会产生内存不足的异常。
这是我正在使用的代码。
for循环:
for (File file : files)
{
String fileName = file.getName();
String filePath = file.getAbsolutePath();
ExecutorService executor = Executors.newSingleThreadExecutor();
Task ts = new Task(filePath);
Future<String> future = executor.submit(ts);
try {
System.out.println("@@ Started.. " + fileName );
System.out.println(future.get(10, TimeUnit.MINUTES));
System.out.println("@@ Finished!" + fileName);
} catch (TimeoutException e) {
System.out.println("@@ Terminated!" + fileName);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
shutdownAndAwaitTermination(executor, future);
future.cancel(true);
}
}
shutdownAndAwaitTermination(,) 方法:
// http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html
public static void shutdownAndAwaitTermination(ExecutorService pool, Future<String> futureObj) {
pool.shutdown();
try {
if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
pool.shutdownNow();
if (!pool.awaitTermination(60, TimeUnit.SECONDS))
{
System.err.println("Pool did not terminate");
}
}
} catch (InterruptedException ie) {
pool.shutdownNow();
Thread.currentThread().interrupt();
}
}
}
任务类:
class Task implements Callable<String> {
String fName = "";
Task(String file)
{
fName = file;
}
@Override
public String call() throws Exception {
while(!Thread.currentThread().isInterrupted())
{
// Long running program on file fName.
}
return "Ready!";
}
}
我收到以下异常:
@@ Started.. file1.java
@@ Terminated!file1.java
Pool did not terminate
@@ Started.. file2.java
java.util.concurrent.ExecutionException: java.util.ConcurrentModificationException
at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:262)
at java.util.concurrent.FutureTask.get(FutureTask.java:119)
at controller.Controller.main(Controller.java:75)
Caused by: java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:819)
at java.util.ArrayList$Itr.next(ArrayList.java:791)
at iterator.CFGIterator.combineCFGs(CFGIterator.java:137)
at iterator.CFGIterator.setOneCFG(CFGIterator.java:92)
at iterator.CFGIterator.<init>(CFGIterator.java:41)
at cfg.ClassObj.iterator(ClassObj.java:47)
at taintanalyzer.TaintAnalyzer.analyze(TaintAnalyzer.java:196)
at cfg.ClassObj.accept(ClassObj.java:65)
at taintanalyzer.TaintAnalyzer.analyze(TaintAnalyzer.java:348)
at controller.Task.call(Controller.java:140)
at controller.Task.call(Controller.java:1)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:722)
【问题讨论】:
-
您似乎在
// Long running program中有一个ConcurrentModificationException。 -
当我在 file2 上单独运行时,它不会给我这个异常。我猜,file1 进程没有被终止/杀死,并且仍在使用资源。
-
除非您展示它在做什么,否则我们无能为力(最好是一个小的可重现示例。)
-
它基本上是一种在该文件上运行的静态污点分析算法。不知道我可以在这里粘贴多少代码。而且它是一个研究工具,所以不能分享太多逻辑。
-
如果您发布更多堆栈跟踪,或者查看它,它会告诉您它发生在哪里。否则,你能证明它与未完成的
ExecutorService有什么关系吗?
标签: java multithreading executorservice