zoukankan      html  css  js  c++  java
  • 结束线程方法2 Java提供的中断机制

    package com.mozq.thread.interrupt;
    /**
     *     注意:调用interrupt()方法,并不会结束线程。
     *     结束线程的语义:需要我们自己使用3个中断方法构建。
     * 
     * 没有任何语言方面的需求一个被中断的线程应该终止。
     * 中断一个线程只是为了引起该线程的注意,被中断线程可以决定如何应对中断。
     * 某些线程非常重要,以至于它们应该不理会中断,而是在处理完抛出的异常之后继续执行。
     * 但是更普遍的情况是,一个线程将把中断看作一个终止请求,这种线程的run方法遵循如下形式
    public void run() {
        try {
            ...
             * 不管循环里是否调用过线程阻塞的方法如sleep、join、wait,这里还是需要加上
             * !Thread.currentThread().isInterrupted()条件,虽然抛出异常后退出了循环,显
             * 得用阻塞的情况下是多余的,但如果调用了阻塞方法但没有阻塞时,这样会更安全、更及时。
            while (!Thread.currentThread().isInterrupted()&& more work to do) {
                do more work 
            }
        } catch (InterruptedException e) {
            //线程在wait或sleep期间被中断了
        } finally {
            //线程结束前做一些清理工作
        }
    }
    
    上面是while循环在try块里,如果try在while循环里时,因该在catch块里重新设置一下中断标示,
    因为抛出InterruptedException异常后,中断标示位会自动清除,此时应该这样:
    public void run() {
        while (!Thread.currentThread().isInterrupted()&& more work to do) {
            try {
                ...
                sleep(delay);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();//重新设置中断标示
            }
        }
    }
    
     *     结束线程方法2:interrupt()方法,interrupted()方法和isInterrupted()方法
     *     该方法的中断语义详细定义在说明文档中。和通常所说的中断意思不一致。
     *     interrupt()方法用于设置:
     *         如果线程处于wait,sleep,join阻塞,则会发生中断异常。中断状态为被清除。
     *         一般情况则导致中断状态位被设置
     *     isInterrupted()检测不清除
     *     interrupted()检测并清除。
     *     通过这3个方法,适用于一个线程向另一个线程发送信息,并被B线程处理。
     *     可以用来实现线程A根据情况结束线程B的语义。
     *     
     *     分成2种情况,1.线程处于阻塞状态2.线程处于正常运行
     *     线程处于正常运行
     * public class ThreadSafe extends Thread {
            public void run() { 
                while (!isInterrupted()){
                    //do something, but no throw InterruptedException
                }
            } 
        }
        线程处于阻塞状态
        public class ThreadSafe extends Thread {
            public void run() { 
                while (!isInterrupted()){ //非阻塞过程中通过判断中断标志来退出
                    try{
                        Thread.sleep(5*1000);//阻塞过程捕获中断异常来退出
                    }catch(InterruptedException e){
                        e.printStackTrace();
                        break;//捕获到异常之后,执行break跳出循环。
                    }
                }
            } 
        }
    1
     * @author jie
     *
     */
    public class MyInterruptMethod {
        public static void main(String[] args) {
            Thread t = new Thread() {
                //方法1:
                /*
                @Override
                public void run() {
                    try {
                        while(!Thread.currentThread().isInterrupted()) {
                            System.out.println(Thread.currentThread().getName() + "...run");
                            Thread.sleep(100);
                        }
                    } catch (InterruptedException e) {}
                }
                */
                @Override
                public void run() {
                        while(!Thread.currentThread().isInterrupted()) {
                            System.out.println(Thread.currentThread().getName() + "...run");
                            try {
                                Thread.sleep(10);
                            } catch (InterruptedException e) {
                                //因为虚拟机处理interrupt调用时,如果方法处于阻塞,会抛出异常并清除中断标志,所以此处需要重置。
                                Thread.currentThread().interrupt();
                                //return;
                                //break;
                            }
                        }
                }
                
            };
            t.start();
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //业务逻辑。。。
            //此处想结束线程
            t.interrupt();
        }
    }
  • 相关阅读:
    机器视觉-halcon学习笔记1
    c#桌面窗体软件【学习笔记】
    Csharp学习笔记 重载
    unity学习笔记——第一人称
    Csharp学习笔记_kita (第二天)namespace
    try ,catch ,finally执行流程
    开发之统一异常处理
    git开发日常使用总结
    mysql5.7绿色版配置以及找不到 mysql服务问题解决
    正则表达式,将数据库字段转换为驼峰式
  • 原文地址:https://www.cnblogs.com/mozq/p/10414190.html
Copyright © 2011-2022 走看看