2016-07-27 32 views
0

很多帖子說我們可以在ServletContextListener中使用ScheduledExecutorService。但我想在某種情況下啓動計時器,然後在另一種情況下停止計時。例如,從客戶端A在請求A中啓動一個定時器,在客戶端A或客戶端B的請求B中停止它。我應該將定時器存儲在會話中嗎?如何動態地啓動和結束tomcat servlet請求中的計時器或計劃作業?

真正的問題是這樣的:我從網絡請求創建一個訂單,我想取消訂單,如果它沒有在24小時後付款。

爲了把事情說清楚,我想這樣的情況:我從一個Web請求創建一個對象,我想刪除的對象,如果它沒有被10秒鐘後處理。在這麼短的時間內,每5到8秒鐘進行一次計劃工作是否很好?我想在10秒或甚至1秒後正好完成這項工作。

回答

0

通常這種事情會做的計劃後臺任務,將檢查您的訂單那些已經過期,需要取消的倉庫,你不應該需要使用HTTP會話這一點。

在您的Order類中,您可以添加一個屬性,該屬性是在請求A中創建的時間戳,有助於查找它們。

然後創建一個調度程序:

ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); 

創建一個Runnable任務,將檢查舊的訂單是需要取消:

Runnable cancelUnpaidOrdersTask = new Runnable() { 
     public void run() { 
      // Your code to look for orders where the timestamp is older than 24 hours and then cancel them. 
     } 
    }; 

然後運行該任務每分鐘 - 或者但是往往你覺得你需要根據自己的要求進行檢查。

scheduler.scheduleAtFixedRate(cancelUnpaidOrdersTask, 0, 1, TimeUnit.MINUTES); 

中的Javadoc的更多細節ScheduledExecutorService

+0

這裏這樣的回答解釋瞭如何從一個網絡環境中實例化一個執行服務:http://stackoverflow.com/a/9186070/2892670 – tchambers

+0

感謝。但我想要一些不同的東西。我編輯我的問題來說清楚。 –

+0

我不知道,這是一個很好的設計,但你可以使用[PassiveExpiringMap(https://commons.apache.org/proper/commons-collections/apidocs/org/apache/commons/collections4/map/ PassiveExpiringMap.html)來存儲對象 - 大概您需要某種ID或密鑰來查找它們。 Guava在[CacheBuilder](https://google.github.io/guava/releases/17.0/api/docs/com/google/common/cache/CacheBuilder.html)中有類似的概念,您可以在其中使用'.expireAfterWrite (10,TimeUnit.SECONDS)'方法。 – tchambers