zoukankan      html  css  js  c++  java
  • java基础知识回顾之java Thread类学习(十二)-- 线程中断

    官方文档翻译:

     

          如果本线程是处于阻塞状态:调用线程的wait(), wait(long)或wait(long, int)会让它进入等待(阻塞)状态,或者调用线程的join(), join(long), 

    join(long, int), sleep(long), sleep(long, int)也会让它进入阻塞状态。若线程在阻塞状态时,调用了它的interrupt()方法,那么

    它的“中断状态”会被清除并且会收到一个InterruptedException异常。例如,线程通过wait()进入阻塞状态,此时通过interrupt()中断该线程;

    调用interrupt()会立即将线程的中断标记设为“true”,但是由于线程处于阻塞状态,所以该“中断标记”会立即被清除为“false”,同时,会产生一个InterruptedException的异常。

        如果线程被阻塞在一个Selector选择器中,那么通过interrupt()中断它时;线程的中断标记会被设置为true,并且它会立即从选择操作中返回。

        如果不属于前面所说的情况,那么通过interrupt()中断线程时,它的中断标记会被设置为“true”。中断一个“已终止的线程”不会产生任何操作。

    线程处于“阻塞状态”和“运行状态”的终止方式如下:

    (1)使用isInterrupted判断,使用interrupt中断

    @Override
    public void run() {
        try {
            // 1. isInterrupted()保证,只要中断标记为true就终止线程。
            while (!isInterrupted()) {
                // 执行任务...
            }
        } catch (InterruptedException ie) {  
            // 2. InterruptedException异常保证,当InterruptedException异常产生时,线程被终止。
        }
    }

    例子1:

    package concurrentMy.interrupts;
    
    /**
     * 
     * (interrupt()常常被用来终止“阻塞状态”线程。)
     *
     * <p>
     * 修改历史:                                            <br>  
     * 修改日期            修改人员       版本             修改内容<br>  
     * -------------------------------------------------<br>  
     * 2016年11月3日 下午2:56:44   user     1.0        初始化创建<br>
     * </p> 
     *
     * @author        Peng.Li 
     * @version        1.0  
     * @since        JDK1.7
     * 
    
    
    运行结果:
    
    A线程的状态: (NEW) is new
    A线程的状态: (RUNNABLE) is start
    A线程的状态: (RUNNABLE) loop 1
    A线程的状态: (RUNNABLE) loop 2
    A线程的状态: (TIMED_WAITING) is interrupted
    A线程的状态: (RUNNABLE) catch InterruptedException.
    A线程的状态: (TERMINATED) is interrupted now
    
    结果说明:1.主线程通过    new ThreadMy("A")创建线程t1,之后之后通过t1.start()启动线程A。
            2.线程A启动之后,会不断的检查它的中断标识,如果中断标识为false,则休眠100ms
            3.t1休眠之后,会切换到主线程main,主线程再次运行,会执行t1.interrupt();中断A线程,
            A收到中断指令后,将A线程的中断标识设置成“false”,而且会抛出InterruptedException异常
     * 
     */
    
    class ThreadMy extends Thread {
    
        public ThreadMy(String name) {
            super(name);
        }
    
        @Override
        public void run() {
            int i = 0;
            try {
                //1. isInterrupted()保证,只要中断标记为true就终止线程。
                while (!isInterrupted()) {
                    //线程A休眠,进入阻塞状态
                    Thread.sleep(100);
                    i++;
                    // 返回当前线程的状态
                    System.out.println(Thread.currentThread().getName() + "线程的状态: (" + this.getState() + ") loop " + i);
                }
                
            } catch (InterruptedException e) {
                // 2. InterruptedException异常保证,当InterruptedException异常产生时,线程被终止。
                // TODO: handle exception
                System.out.println(Thread.currentThread().getName() + "线程的状态: (" + this.getState() + ") catch InterruptedException.");
            }
    
        }
    }
    
    public class Demo1_interrupt {
        public static void main(String[] args) {
            try {
                // 新建线程A
                ThreadMy t1 = new ThreadMy("A");
                System.out.println(t1.getName() + "线程的状态: (" + t1.getState() + ") is new");
                // 启动线程A
                t1.start();
                System.out.println(t1.getName() + "线程的状态: (" + t1.getState() + ") is start");
                // 主线程休眠300毫秒,然后main线程给t1发送指令
                Thread.sleep(300);
                t1.interrupt();
                
                System.out.println(t1.getName() + "线程的状态: (" + t1.getState() + ") is interrupted");
    
                // 主线程再休眠300ms,查看A线程的状态
                Thread.sleep(300);
                System.out.println(t1.getName() + "线程的状态: (" + t1.getState() + ") is interrupted now");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
        }
    }

    (2)安全的终止线程,使用volatile boolean变量。

    package concurrentMy.interrupts;
    
    /**
     * 
     *
     * <p>
     * 修改历史:                                            <br>  
     * 修改日期            修改人员       版本             修改内容<br>  
     * -------------------------------------------------<br>  
     * 2016年11月3日 下午2:56:44   user     1.0        初始化创建<br>
     * </p> 
     *
     * @author        Peng.Li 
     * @version        1.0  
     * @since        JDK1.7
     * 
    
    安全的终止线程,使用volatile boolean变量。
    
    运行结果:
    
    A线程的状态: (NEW) is new
    A线程的状态: (RUNNABLE) is start
    A线程的状态: (RUNNABLE) loop 1
    A线程的状态: (RUNNABLE) loop 2
    A线程的状态: (TIMED_WAITING) is interrupted
    A线程的状态: (RUNNABLE) loop 3
    count3
    A线程的状态: (TERMINATED) is interrupted now
    
    
    结果说明:1.主线程通过    new ThreadMy("A")创建线程t1,之后之后通过t1.start()启动线程A。
            2.线程A启动之后,会不断的检查它的中断标识,如果中断标识为true,则休眠100ms
            3.t1休眠之后,会切换到主线程main,主线程再次运行,会执行t1.cancel();中断A线程,
            A收到中断指令后,将A线程的中断标识设置成“false”,清除中断标识,而且会抛出InterruptedException异常
     * 
     * 
     *  
     */
    
    class ThreadMy1 extends Thread {
    
        // volatile的应用,保证线程之间对on标识的可见性,一个线程(主线程)改了标识,
        // 即调用A线程的cancel方法取消或者停止了任务(A线程的执行,则立即对这个线程(A线程)可见
        private volatile boolean on = true;
    
        public ThreadMy1(String name) {
            super(name);
        }
    
        /**
         * 
         * (// 通过on 变量来控制是否需要停止任务并且终止任务) 
         *
         */
        public void cancel() {
            on = false;
        }
    
        @Override
        public void run() {
            int i = 0;
            try {
                // on = false 的时候中断线程
                while (on /* && !isInterrupted() */) {
                    // 线程A休眠,进入阻塞状态
                    Thread.sleep(100);
                    i++;
                    // 返回当前线程的状态
                    System.out.println(Thread.currentThread().getName() + "线程的状态: (" + this.getState() + ") loop " + i);
                }
                System.out.println("count" + i);
            } catch (InterruptedException e) {
                // 2. InterruptedException异常保证,当InterruptedException异常产生时,线程被终止,这个地方加一些日志操作
                // TODO: handle exception
                System.out.println(Thread.currentThread().getName() + "线程的状态: (" + this.getState() + ") catch InterruptedException.");
            }
    
        }
    }
    
    public class Demo2_interrupt {
        public static void main(String[] args) {
            try {
                // 新建线程A
                ThreadMy1 t1 = new ThreadMy1("A");
                System.out.println(t1.getName() + "线程的状态: (" + t1.getState() + ") is new");
                // 启动线程A
                t1.start();
                System.out.println(t1.getName() + "线程的状态: (" + t1.getState() + ") is start");
                // 主线程休眠300毫秒,然后main线程给t1发送指令
                Thread.sleep(300);
                // 中断线程
                t1.cancel();
                System.out.println(t1.getName() + "线程的状态: (" + t1.getState() + ") is interrupted");
    
                // 主线程再休眠300ms,查看A线程的状态
                Thread.sleep(300);
                System.out.println(t1.getName() + "线程的状态: (" + t1.getState() + ") is interrupted now");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
        }
    }
  • 相关阅读:
    2019-8-22学习笔记---文件上传与读取
    JS字符串的操作
    JS控制台打印星星,总有你要的那一款~呐~给你小心心哦~~~❤
    DOM的操作(增删改查)
    js上传视频(jquery.form.js)
    vue单页面模板说明文档(3)
    vue单页面模板说明文档(2)
    vue单页面模板说明文档(1)
    js 通过url获取里面的参数值
    ios点击输入框,界面放大解决方案
  • 原文地址:https://www.cnblogs.com/200911/p/6027416.html
Copyright © 2011-2022 走看看