美文网首页
中断和InterruptedException

中断和InterruptedException

作者: 大风过岗 | 来源:发表于2020-11-04 10:12 被阅读0次

    1、代码示例

    public static void main(String[] args) throws Exception {
            Thread t = new Thread(new Runnable() {
                private  Integer count = 1;
                @Override
                public void run() {
                    //如果发现中断标志,就停止运行
                    while (true && !Thread.currentThread().isInterrupted()){
                        try{
                            count++;
                            if(count > 200){
                                count =1000;
                            }
                            Thread.sleep(2000);
                        }catch (InterruptedException e){
                            //发生中断之后,继续执行
                            //System.out.println("发生中断之后,结束运行");
                            //break;
                            System.out.println("中断发生后的中断状态"); //其实就是基于状态机的线程生命周期控制
                            //收到InterruptedException之后,线程的中断状态会被清除,此时的中断标志位false。
                            System.out.println(Thread.currentThread().isInterrupted());
                            //Thread.currentThread().interrupt(); 会把中断标志置为true
                            Thread.currentThread().interrupt();
                            System.out.println("调用完interrupt方法之后");
                            System.out.println(Thread.currentThread().isInterrupted());
                            //return
                        }
                    }
                }
            });
            t.start();
            Thread.sleep(1000);
            System.out.println("主线程睡眠结束,开始中断");
            t.interrupt();
            Thread.State state = t.getState();
            System.out.println(state);
        }
    

    2、如何处理中断

    当发生中断异常时,我们有几种处理手段:

    1. 不捕获InterruptedException ,而把其传播给调用者来处理

    2. 捕获InterruptedException,执行特定的清理动作,并 rethrowing InterruptedException

    3. 捕获InterruptedException,记录中断日志,并恢复中断标志

    4. 捕获InterruptedException,并吃掉它 (不要这样做

    2.1 不捕获InterruptedException ,而把其传播给调用者来处理

    public class TaskQueue {
        private static final int MAX_TASKS = 1000;
     
        private BlockingQueue<Task> queue 
            = new LinkedBlockingQueue<Task>(MAX_TASKS);
     
        public void putTask(Task r) <strong>throws InterruptedException</strong> { 
            queue.put(r);
        }
     
        public Task getTask() <strong>throws InterruptedException</strong> { 
            return queue.take();
        }
    }
    

    2.2 捕获InterruptedException执行特定的清理动作并rethrowing InterruptedException

    public class PlayerMatcher {
        private PlayerSource players;
     
        public PlayerMatcher(PlayerSource players) { 
            this.players = players; 
        }
     
        public void matchPlayers() <strong>throws InterruptedException</strong> { 
            Player playerOne, playerTwo;
             try {
                 while (true) {
                     playerOne = playerTwo = null;
                     // Wait for two players to arrive and start a new game
                     playerOne = players.waitForPlayer(); // could throw IE
                     playerTwo = players.waitForPlayer(); // could throw IE
                     startNewGame(playerOne, playerTwo);
                 }
             }
             catch (InterruptedException e) {  
                 // If we got one player and were interrupted, put that player back
                 if (playerOne != null)
                     players.addFirst(playerOne);
                 // Then propagate the exception
                 <strong>throw e;</strong>
             }
        }
    }
    

    2.3 捕获InterruptedException,记录中断日志,并恢复中断标志

    public class TaskRunner implements Runnable {
        private BlockingQueue<Task> queue;
     
        public TaskRunner(BlockingQueue<Task> queue) { 
            this.queue = queue; 
        }
     
        public void run() { 
            try {
                 while (true) {
                     Task task = queue.take(10, TimeUnit.SECONDS);
                     task.execute();
                 }
             }
             catch (InterruptedException e) { 
                 // Restore the interrupted status
                 <strong>Thread.currentThread().interrupt();</strong>
             }
        }
    }
    

    2.4 捕获InterruptedException并吃掉它 (错误的做法)

    // Don't do this 
    public class TaskRunner implements Runnable {
        private BlockingQueue<Task> queue;
     
        public TaskRunner(BlockingQueue<Task> queue) { 
            this.queue = queue; 
        }
     
        public void run() { 
            try {
                 while (true) {
                     Task task = queue.take(10, TimeUnit.SECONDS);
                     task.execute();
                 }
             }
             catch (InterruptedException swallowed) { 
                 /* DON'T DO THIS - RESTORE THE INTERRUPTED STATUS INSTEAD */
             }
        }
    }
    

    3、参考文献

    3.1 处理中断IBM

    相关文章

      网友评论

          本文标题:中断和InterruptedException

          本文链接:https://www.haomeiwen.com/subject/xtnwvktx.html