簡體   English   中英

如何強制Java REST應用程序進入空閑狀態?

[英]How to force a Java REST application into Idle State?

我有一個約30個端點的REST應用程序。 除了這些,用戶還可以提交需要處理20-60分鍾的后台任務。 有時很明顯,提交的請求永遠不會從日志中完成,但是,我唯一能做的就是重新部署相同版本的代碼。

我希望能夠像通過mySQL殺死進程一樣殺死進程

'Show Process List' -> 'Kill <ProcessId>'.

我試圖用Thread.currentThread()。interrupt()來實現,但這實際上並沒有做任何事情。 我在整個應用程序中多次使用CompletionService和多線程來加速進程。

我的目標是我應該能夠調用此API,以使應用程序返回到沒有進程運行時的狀態。 我檢查了這篇文章,但似乎所有人都對此警告。

如何查找和停止所有當前正在運行的線程?

能做到嗎?

為什么Thread.currentThread()。interrupt()不起作用

Thread.currentThread()返回正在運行的當前線程的Thread對象,因此,如果在后台任務線程之外調用此對象,它將不會返回對后台線程的引用。 如果要引用您的后台線程,則必須自己對其進行跟蹤。

thread.interrupt()在您的線程上設置一個中斷標志。 但是,如果您的線程從不顯式檢查中斷標志,則它不會執行任何操作。 您將必須定期檢查后台任務中的中斷標志,然后采取適當的措施。

if (Thread.currentThread().isInterrupted()) {
  finishWork(); // Close any resources used.
  return;
}

對於您的用例,我實際上不鼓勵在后台任務上使用interrupt(),尤其是在使用線程池的情況下。 特別是,如果您使用的是Threadpool,則可以重復使用同一線程來運行多個后台任務。 由於線程已被重用,因此可能會意外中斷您從未打算執行的后台任務。

如何停止后台任務

這將需要做大量的工作,但這是可行的。 下面,我描述一個非常基本的實現,它將足以滿足您的用例。

  1. 首先,您將必須創建類似SpringBoot服務的內容。 這是一個單例類,被注入到執行其余端點的所有類中。 該服務將是后台任務跟蹤器,該跟蹤器保留從任務ID到指示是否應終止任務的標志的映射。
  2. 接下來,您將必須創建一個rest終結點以終止后台任務。 其余端點應使用任務ID終止為查詢參數或路徑參數。
  3. 當端點執行時,您可以在后台任務跟蹤器上調用終止方法,該方法將翻轉標志以指示任務應終止。 注意:您的后台任務可能在實際終止之前已經完成,因此您的代碼應處理這種極端情況。
  4. 啟動后台任務時,應為其提供對后台任務跟蹤器的引用。
  5. 您的后台任務應該做的第一件事就是創建一個唯一的任務ID。 您可以從使用UUID.randomUUID()
  6. 創建任務ID后,將其提供給您的后台任務跟蹤器。
  7. 在后台任務的日志中打印任務ID。
  8. 后台任務可以繼續執行其工作,但是它應定期檢查后台任務跟蹤器是否已被取消。 如果不繼續處理,如果是,則關閉所有使用的資源並返回。
  9. 在退出后台任務之前,應將其從后台任務跟蹤器中刪除,以避免內存泄漏。

重要筆記

在執行此操作之前,請務必先閱讀如何正確同步Java中線程之間的通信。 這是一個很好的資源https://docs.oracle.com/javase/tutorial/essential/concurrency/sync.html

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM