以下代码应该向手机发送短信并在操作成功时返回。如果操作超过1分钟没有成功,它应该中止操作并尝试发送另一条消息。代码在测试环境中运行良好,但是当它在生产环境中实现时,它似乎永远等待,直到操作成功忽略60秒规则。如果有人能发现代码工作中的任何问题,我希望你告诉我。
public synchronized String sendSms(MessageData messageData) {
class Task implements Callable<String> {
private MessageData messageData;
public Task(MessageData messageData) {
this.messageData = messageData;
}
@Override
public String call() throws Exception {
System.out.println("Sending MPT >>> " + "Number : " + messageData.getToAddress() + ", Message : "
+ messageData.getMessage());
SendSMS.send(messageData.getToAddress(), messageData.getMessage(),
Long.toString(messageData.getSyskey()));
//The real code that sends the message
//***
return "1";
}
}
ExecutorService executor = Executors.newSingleThreadExecutor();
Task t = new Task(messageData);
Future<String> future = executor.submit(t);
try {
System.out.println("Started..");
future.get(60, TimeUnit.SECONDS);
executor.shutdown();
return "1";
} catch (TimeoutException e) {
future.cancel(true);
executor.shutdown();
return "-1";
} catch (InterruptedException e) {
executor.shutdown();
return "-1";
} catch (ExecutionException e) {
executor.shutdown();
return "-1";
}
}
答案 0 :(得分:1)
这个答案总结了评论中收集到的零碎信息。
OP使用API发送短信。每个send都被委托给一个以Callable
实现的通常短命的线程。不幸的是,API send
功能可能会无限期地阻止。
使用可以阻止的API时,存在三种常见情况:
使用标准Java技术可以轻松处理前两种情况。
OP的问题在于API似乎属于第三种类型。在这种情况下,主线程可以在60秒超时后放弃Callable
线程,但如果send()
API调用永远不会返回,则线程永远不会终止。这将导致线程及其资源(网络端口,内存等)的永久性泄漏,这将要求定期重新启动应用程序以回收泄漏的资源。