簡體   English   中英

為線程編寫舒適的暫停/停止方法

[英]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.submitExecutor.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.

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