我的应用程序依靠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);
上设置超时,然后按照this和this的建议在抛出异常时取消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也未提供超时方法。
在此示例中,有什么方法可以强制阻止操作终止?
谢谢!
答案 0 :(得分:0)
首先,我建议您进行线程转储,以找到挂起的确切位置。同时,请尝试查看您使用的库源代码,以了解可能导致此挂起的原因。库很可能会调用一些与中断无关的内容。幸运的是,此类操作并不多,并且大多数与套接字I / O有关。我在JDK中见过的最全面的列表在《 Java Concurrency in Practice》一书的第7.1.6章中。套接字I / O对于您的情况来说似乎是一个合理的解释,因为客户端库肯定会通过HTTP调用ebay API。如果它使用标准的JDK HTTP客户端,请尝试设置these timeouts。否则,唯一可行的解决方案是更改该库的源代码以使其对中断负责或使用另一个:)