gracefully cancel/shutdown the thread

for something we should care it when you read this article

1. Interrupt operation in synchronized code block

使用synchronized關鍵字獲取鎖的過程中不響應中斷請求,這是synchronized的侷限性,如果這對程序是一個問題,應該使用顯式鎖,java中的Lock接口,它支持以響應中斷的方式獲取鎖。對於Lock.lock(),可以改用Lock.lockInterruptibly(),可被中斷的加鎖操作,它可以拋出中斷異常。等同於等待時間無限長的Lock.tryLock(long time, TimeUnit unit)。


2. Interrupt operation in IO Stream operation

(1). 實現此InterruptibleChannel接口的通道是可中斷的:如果某個線程在可中斷通道上因調用某個阻塞的 I/O 操作
(常見的操作一般有這些:serverSocketChannel. accept()、socketChannel.connect、socketChannel.open、socketChannel.read、socketChannel.write、fileChannel.read、fileChannel.write)而進入阻塞狀態,而另一個線程又調用了該阻塞線程的 interrupt 方法,這將導致該通道被關閉,並且已阻塞線程接將會收到ClosedByInterruptException,並且設置已阻塞線程的中斷狀態。
(2). 另外,如果已設置某個線程的中斷狀態並且它在通道上調用某個阻塞的 I/O 操作,則該通道將關閉並且該線程立即接收到 ClosedByInterruptException;並仍然設置其中斷狀態。
(3). 如果線程阻塞於Selector調用,則線程的中斷標誌位會被設置,同時,阻塞的調用會立即返回。


especially,when call the InputStream read(),it can’t be interrupt truly,and if the Stream don’t receive some data,the read method would wait some input data (but the thread state is runnable),and don’t response the interrupt opreation. Similar to synchronized, calling interrupt() only sets interrupt flags for threads, not really “interrupts” it

you can see some code about this:

public class InterruptReadDemo {
    private static class A extends Thread {
        @Override
        public void run() {
            while (!Thread.currentThread().isInterrupted()) {
                try {
                    System.out.println(System.in.read());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("exit");
        }
        public void cancel() {
            try {
                System.in.close();
            } catch (IOException e) {
            }
            interrupt();
        }
    }
    public static void main(String[] args) throws InterruptedException {
        A t = new A();
        t.start();
        Thread.sleep(100);
        t.interrupt(); // the false operation
        t.cancel();// the true operation
    }
}

the A thread cannot shutdown when the main method call the “t.interrupt()” , the IO "System.in.read( ) " method would be blocked forever unless you input some char. however, when you call the custom Method “t.cancel()”, it can close the stream and set the interrput flag to let the Thread shutdown, It is gracefully way, don’t you think that guy?


3. It seems that the interrupt method may not really "shut down” thread.

It’s just a collaboration mechanism. If you don’t understand what a thread is doing, you shouldn’t call the thread’s interrupt method so that you can cancel the thread.


4. How to gracefully cancel/shutdown the thread

  1. 對於以線程提供服務的程序模塊而言,它應該封裝取消/關閉操作,提供單獨的取消/關閉方法給調用者,類似於InterruptReadDemo中演示的cancel方法,外部調用者應該調用這些方法而不是直接調用interrupt。

  2. Java併發庫的一些代碼就提供了單獨的取消/關閉方法,比如說,Future接口提供瞭如下方法以取消任務:
    boolean cancel(boolean mayInterruptIfRunning);

    再比如,ExecutorService提供瞭如下兩個關閉方法:
    void shutdown();
    List shutdownNow();


2.上代碼

 class Runner implements Runnable{

        private volatile boolean on = true;
        
        @Override
        public void run() {
            while(on && !Thread.currentThread().isInterrupted()){
                //do something
            }
            
            {
                //do something you wanna release or close 
            }
        }
        
        //use this way, thead has time to realse some resource
        //it is very gracefully
        public void cancle(){ 
            on = false;
        }
        
        
    }




《Interrupt中斷線程注意點》
https://www.cnblogs.com/java-spring/p/8315407.html
《線程的中斷(interrupt)機制》
https://blog.csdn.net/a837199685/article/details/55846746

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章