zoukankan      html  css  js  c++  java
  • Thread类中interrupt()、interrupted()和isInterrupted()方法详解

    首先看看官方说明:

    interrupt()方法

    其作用是中断此线程(此线程不一定是当前线程,而是指调用该方法的Thread实例所代表的线程),但实际上只是给线程设置一个中断标志,线程仍会继续运行。

    interrupted()方法

    作用是测试当前线程是否被中断(检查中断标志),返回一个boolean并清除中断状态,第二次再调用时中断状态已经被清除,将返回一个false。

    isInterrupted()方法

    作用是只测试此线程是否被中断 ,不清除中断状态。

    下面我们进行测试说明:

    定义一个MyThread类,继承Thread,如下:

    public class MyThread extends Thread {
        @Override
        public  void run() {
            for (int i = 0; i < 10; i++) {
                System.out.println("i="+(i+1));
            }
        }
    }
    

    在main方法中测试:

    public class Do {
    	public static void main(String[] args ) {
    		MyThread thread=new MyThread();
    		thread.start();
    		thread.interrupt();
    		System.out.println("第一次调用thread.isInterrupted():"+thread.isInterrupted());
    		System.out.println("第二次调用thread.isInterrupted():"+thread.isInterrupted());
    		System.out.println("thread是否存活:"+thread.isAlive());
    	}
    }
    

    输出如下:

    从结果可以看出调用interrupt()方法后,线程仍在继续运行,并未停止,但已经给线程设置了中断标志,两个isInterrupted()方法都会输出true,也说明isInterrupted()方法并不会清除中断状态。

    下面我们把代码修改一下,多加两行调用interrupted()方法:

    public class Do {
    	public static void main(String[] args ) {
    		MyThread thread=new MyThread();
    		thread.start();
    		thread.interrupt();
    		System.out.println("第一次调用thread.isInterrupted():"+thread.isInterrupted());
    		System.out.println("第二次调用thread.isInterrupted():"+thread.isInterrupted());
                        //测试interrupted()函数
    		System.out.println("第一次调用thread.interrupted():"+thread.interrupted());
    		System.out.println("第二次调用thread.interrupted():"+thread.interrupted());
    		System.out.println("thread是否存活:"+thread.isAlive());
    	}
    }

    输出如下:

    从输出结果看,可能会有疑惑,为什么后面两个interrupted方法输出的都是false,而不是预料中的一个true一个false?注意!!!这是一个坑!!!上面说到,interrupted()方法测试的是当前线程是否被中断,当前线程!!!当前线程!!!这里当前线程是main线程,而thread.interrupt()中断的是thread线程,这里的此线程就是thread线程。所以当前线程main从未被中断过,尽管interrupted()方法是以thread.interrupted()的形式被调用,但它检测的仍然是main线程而不是检测thread线程,所以thread.interrupted()在这里相当于main.interrupted()。对于这点,下面我们再修改进行测试。

    Thread.currentThread()函数可以获取当前线程,下面代码中获取的是main线程

    public class Do {
    	public static void main(String[] args ) throws InterruptedException {
    		Thread.currentThread().interrupt();
    		System.out.println("第一次调用Thread.currentThread().interrupt():"
    				+Thread.currentThread().isInterrupted());
    		System.out.println("第一次调用thread.interrupted():"
    				+Thread.currentThread().interrupted());
    		System.out.println("第二次调用thread.interrupted():"
    				+Thread.currentThread().interrupted());
    	}
    }
    

    这里都是针对当前线程在操作,如果interrupted()方法有检测中断并清除中断状态的作用,预料中的输出应该是true-true-false,实际输出如下:

    结果证明猜想是正确的。

    若果想要是实现调用interrupt()方法真正的终止线程,则可以在线程的run方法中做处理即可,比如直接跳出run()方法使线程结束,视具体情况而定,下面是一个例子。

    修改MyThread类:

    public class MyThread extends Thread {
        @Override
        public  void run() {
            for (int i = 0; i < 1000; i++) {
                System.out.println("i="+(i+1));
                if(this.isInterrupted()){
                    System.out.println("通过this.isInterrupted()检测到中断");
                    System.out.println("第一个interrupted()"+this.interrupted());
                    System.out.println("第二个interrupted()"+this.interrupted());
                    break;
                }
            }
            System.out.println("因为检测到中断,所以跳出循环,线程到这里结束,因为后面没有内容了");
        }
    }

    测试MyThread:

    public class Do {
    	public static void main(String[] args ) throws InterruptedException {
    		MyThread myThread=new MyThread();
    		myThread.start();
    		myThread.interrupt();
    		//sleep等待一秒,等myThread运行完
    		Thread.currentThread().sleep(1000);
    		System.out.println("myThread线程是否存活:"+myThread.isAlive());
    	}
    }
    

    结果:

    最后总结,关于这三个方法,interrupt()是给线程设置中断标志;interrupted()是检测中断并清除中断状态;isInterrupted()只检测中断。还有重要的一点就是interrupted()作用于当前线程,interrupt()和isInterrupted()作用于此线程,即代码中调用此方法的实例所代表的线程。

  • 相关阅读:
    在SQLite中使用索引优化查询速度
    SQLite支持的SQL数据操作
    left (outer) join , right (outer) join, full (outer) join, (inner) join, cross join 区别
    深入理解Android内存管理原理(六)
    Merge Sorted Array
    Sort Colors
    Construct Binary Tree from Preorder and Inorder Traversal
    Binary Tree Postorder Traversal
    Symmetric Tree
    Rotate Image
  • 原文地址:https://www.cnblogs.com/makai/p/12596083.html
Copyright © 2011-2022 走看看