[英]Writing a comfortable pause/stop method for a Thread
對於Java中的Thread子類,我試圖編寫一個方法checkPauseAndStop()
,其目的是使一線好,我可以在run()
方法中定期調用該方法以檢查是否存在暫停/停止請求並采取相應的措施。
當功能完全正常時,通過InterruptedException
處理停止線程,該方法強制將run()代碼置於try-catch中,並且容易出錯
(例如Thread.sleep()不再告訴您它可能會拋出此類異常)。
有沒有什么好的方法可以在方法內部處理停止線程而不會影響run()方法?
代碼示例:
public class SuspendableThread extends Thread
{
private Semaphore lock = new Semaphore(1);
public void checkPauseRequest() throws InterruptedException
{
if (isInterrupted())
throw new InterruptedException();
lock.acquire();
lock.release();
}
@Override
public void run()
{
try
{
while (true)
{
// Do_stuff
checkPauseRequest();
}
}
catch (InterruptedException e)
{
return;
}
}
當然,在此特定示例中,根本沒有必要。 為了獲得更大的效果,假設我們有50個或更多的連續塊
// Do_stuff
checkPauseRequest();
而不是一個。
如果您想捕獲發送給線程的中斷,以進行清理,例如,您將無法將整個run()代碼塊放入try / catch異常塊中。 原因是,如果您的線程正在通過條件變量或信號燈(例如,調用wait()
方法)執行任何類型的線程間信號傳遞,則run()代碼塊將立即引發InterruptedException
,如果中斷為線程設置了狀態標志。 但是,如果您要主動檢查線程的中斷狀態,最簡單的方法是噴灑一堆中斷點,也就是您的checkPause()
方法,並放置幾納秒的睡眠時間(您的sleep()
如果設置了中斷標志sleep()
方法將拋出InterruptedException)。 這樣就可以實現您的目標,而不會影響線程性能。
我將使用ScheduledExecutorService
(可以使用Executors.newSingleThreadScheduledExecutor
創建)和enum RunningState { RUNNING, PAUSED, STOPPED }
來進行架構。
當狀態為RUNNING
,我們將繼續安排延遲的任務(使用ScheduledExecutorService.schedule
)。 每個任務都會檢查我們是否仍在RUNNING
,如果是這樣,則使單個循環迭代入隊(使用ExecutorService.submit
或Executor.execute
)。 然后,它為下一次迭代計划一個新的延遲任務(與Timer
不同,您可以使用它,而可能會浪費另一個線程)。
如果狀態為PAUSED
,我們將繼續安排延遲的任務,以檢查返回到RUNNING
狀態的轉換。 但是我們不為實際的循環迭代安排工作項。
如果狀態為“ STOPPED
則我們將停止調度任何其他延遲的任務。
狀態變量可以存儲在一個簡單的volatile
字段中,該字段可以是靜態的(如果只有這些東西之一),也可以包裝在一個代表“線程”的對象中(實際上不再是單個線程) ,但從調用者的角度來看卻很像)。
請確保您要實現的目標確實有意義,並且不要誤入歧途 。 制作任何通用的“一刀切”停止方法並不是一件容易的事,盡管對於Java創建者來說也是如此。 這就是不推薦使用Thread.stop()方法的原因。 ( https://docs.oracle.com/javase/10/docs/api/java/lang/Thread.html#stop() )(並且Thread.destroy()實際上並未實現AFAICT。)
有一個很好的解釋: https : //docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.