使用第3方库时如何在文件上传中使线程阻塞超时

时间:2019-02-18 17:15:05

标签: java multithreading sdk timeout ebay-api

我的应用程序依靠eBay Picture Service将图像从我的桌面上传到eBay服务器。通常,完成上传需要花费几秒钟的时间。但是,有时可能需要几个小时,有时可能永远无法完成。这是无法预测的,API不会引发任何异常。这导致我的应用程序同时调用外部API的次数过多,并且也浪费了系统资源。

我的目标是为上传设置超时时间,如果上传未在规定的时间内成功,则取消基础流程。我试图在import React from "react"; import ReactDOM from "react-dom"; import "antd/dist/antd.css"; import { Dropdown, Menu, Icon } from "antd"; class DropOption extends React.Component { state = { selectedOption : null }; handleMenuClick = e => { this.setState({ selectedOption: e.key }); }; items = [ { key: "option1", text: "CULT-4A", links: [ { text: "option1 - link1", url: "/linkCULT-1" }, { text: "option1 - link2", url: "/linkCULT-2" } ] }, { key: "option2", text: "HIN-4A", links: [ { text: "option2 - link1", url: "/linkHIN-1" }, { text: "option2 - link2", url: "/linkHIN-2" } ] } ]; render() { const currentItem = this.items.find( item => item.key === this.state.selectedOption ); const links = currentItem ? currentItem.links : []; console.log(links); const menu = ( <Menu onClick={this.handleMenuClick}> {this.items.map(item => ( <Menu.Item key={item.key}>{item.text}</Menu.Item> ))} </Menu> ); return ( <div align="center"> <Dropdown overlay={menu}> <a className="ant-dropdown-link" href="#"> Select one option <Icon type="down" /> </a> </Dropdown> {links.length > 0 && ( <div> <ul> {links.map(link => { return ( <li key="{link.url}"> <a href="{link.url}">{link.text}</a> </li> ); })} </ul> </div> )} </div> ); } } export default DropOption; const rootElement = document.getElementById("root"); ReactDOM.render(<DropOption />, rootElement); 上设置超时,然后按照thisthis的建议在抛出异常时取消ExecutorService

future

不幸的是,该解决方案仅在底层线程由于无限循环而继续运行和/或底层操作被设计为理解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()循环中)。但是,在这种情况下,我无法控制基础进程,因此无法在子线程中调用中断。该API也未提供超时方法。

在此示例中,有什么方法可以强制阻止操作终止?

谢谢!

1 个答案:

答案 0 :(得分:0)

首先,我建议您进行线程转储,以找到挂起的确切位置。同时,请尝试查看您使用的库源代码,以了解可能导致此挂起的原因。库很可能会调用一些与中断无关的内容。幸运的是,此类操作并不多,并且大多数与套接字I / O有关。我在JDK中见过的最全面的列表在《 Java Concurrency in Practice》一书的第7.1.6章中。套接字I / O对于您的情况来说似乎是一个合理的解释,因为客户端库肯定会通过HTTP调用ebay API。如果它使用标准的JDK HTTP客户端,请尝试设置these timeouts。否则,唯一可行的解​​决方案是更改该库的源代码以使其对中断负责或使用另一个:)