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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值