如果1分钟内没有成功,则中止操作

时间:2017-03-03 05:11:21

标签: java

以下代码应该向手机发送短信并在操作成功时返回。如果操作超过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";
    }
}

1 个答案:

答案 0 :(得分:1)

这个答案总结了评论中收集到的零碎信息。

OP使用API​​发送短信。每个send都被委托给一个以Callable实现的通常短命的线程。不幸的是,API send功能可能会无限期地阻止。

使用可以阻止的API时,存在三种常见情况:

  1. API&#34;意识到&#34;实现JVM并使其能够响应Java中断异常并终止其操作。
  2. API不支持Java,但有一个超时选项,会导致它在指定的时间段后终止并返回。
  3. 阻止操作可能会无限期阻塞,并且不会被JVM中的操作中断。
  4. 使用标准Java技术可以轻松处理前两种情况。

    OP的问题在于API似乎属于第三种类型。在这种情况下,主线程可以在60秒超时后放弃Callable线程,但如果send() API调用永远不会返回,则线程永远不会终止。这将导致线程及其资源(网络端口,内存等)的永久性泄漏,这将要求定期重新启动应用程序以回收泄漏的资源。