2017-03-03 47 views
0

以下代碼應該發送短信至手機,並在操作成功時返回。如果操作在超過1分鐘內沒有成功,它應該中止操作並嘗試發送另一條消息。代碼在測試環境中運行良好,但是當它在生產環境中實現時,它似乎一直等到操作成功忽略60秒規則爲止。如果有人能夠發現代碼工作中的任何問題,我想請你告訴我。如果在1分鐘內沒有成功,則中止操作

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」 「1」作爲返回值?真?嚴重:這很糟糕。 – GhostCat

+0

你是說它掛在'future.get(60,TimeUnit.SECONDS)'? – shmosel

+0

你有沒有試過調試過?如果是這樣,結果如何?例如,嘗試在調用Future.get(long,TimeUnit)之前和之後放置斷點,並確認(a)最後一個線程實際上到達print語句,並且(b)同一線程不會到達executor.shutdown()。 – Teto

回答

1

這個答案總結了在評論中收集的零碎信息。

OP使用API​​發送SMS消息。每個發送都被委託給一個通常短暫的線程,實現爲Callable。不幸的是,API的send功能顯然可能無限期地阻止。

使用時,可以阻止一個API,三個一般情況下存在:

  1. 該API的JVM的「知道」,並且被實現,以便它可以爲Java中斷響應異常並終止其運行。
  2. API不支持Java,但有一個超時選項,它會導致它在指定的時間段後終止並返回。
  3. 阻塞操作可能會無限期阻塞,並且不會由JVM中的操作中斷。

使用標準Java技術輕鬆處理前兩種情況。

OP的問題是,API似乎是第三種類型。在這種情況下,主線程在60秒超時後可以放棄線程,但如果API調用永不返回,線程將永遠不會終止。這將導致線程及其資源(網絡端口,內存等)的永久性泄漏,這將需要定期重新啓動應用程序以回收泄露的資源。

相關問題