我的应用程序依靠eBay Picture Service将图像从我的桌面上传到eBay服务器。通常,上传完成需要几秒钟。但是,它有时可能需要数小时,偶尔也可能永远不会完成。如果发生这种情况是不可预测的,并且API不会抛出任何异常。这导致我的应用程序同时调用外部API太多次,并且还会占用系统资源。
我的目标是设置上传超时并取消基础流程,如果上传时间不成功。我尝试在ExecutorService
上设置超时,然后在future
和this帖子中建议抛出异常时取消this:
ExecutorService executorService = Executors.newFixedThreadPool(10);
ArrayList<Future<?>> futuresList = new ArrayList<Future<?>>();
for (String singleTask : taskList) {
futuresList.add(executorService.submit( new Runnable(){
@Override
public void run(){
try {
myBlockingTask(singleTask);
} catch (IOException | InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}));
}
try {
future.get(240, TimeUnit.SECONDS);
} catch (Exception e){
e.printStackTrace();
// Stops parent thread from waiting for child but it does not terminate 'child' thread.
// As a result, call(s) to external API continue to increase (rapidly) since the underlying process never actually ends
future.cancel(true);
}
不幸的是,这个解决方案只有当底层线程由于无限循环而继续运行和/或底层操作被设计为理解Thread.isInterrupted()
(如在while()
循环中)时才有效。但是,在这种情况下,我无法控制底层进程,因此我无法在子线程中调用中断。 API也不提供超时方法。
有没有办法在此示例中强制阻止操作终止?
谢谢!
首先,我建议你做一个线程转储,以找到一个挂起的确切位置。同时尝试查看您使用的库的源代码,试图了解可能导致此挂起的原因。最有可能的是,图书馆会调用一些不对中断负责的东西。幸运的是,没有那么多这样的操作,其中大部分都与套接字I / O有关。我见过的JDK最全面的列表出现在“Java Concurrency in Practice”一书的第7.1.6章中。套接字I / O看起来像是对你的案例的合理解释,因为客户端库肯定会通过HTTP调用ebay API。如果它使用标准JDK HTTP客户端尝试设置these timeouts。否则,唯一可行的解决方案是更改库的源代码,使其负责中断或使用另一个:)