线程的中断interrupt,判断是否中断isInterrupt和interrupted的区别

api 含义
public void interrupt() 中断线程,中断并不是真正的中断线程,而只设置标志位(中断位)来通知用户
public boolean isInterrupt() 判断Thread 对象是否中断
public static boolean interrupted 判断 当前线程是否中断,并且清除当前中断状态

 image_1as4prvqmf31unj13asakincvm.png-21.5kB

image_1as4psmlbgfhhhgmm31as71dnp13.png-16.1kB

 

package thread.test;

public class InterruptThread extends Thread{
    @Override
    public void run(){
        super.run();
        try {
        for (int i=0; i < 5000; i++){
        	if (this.isInterrupted()){
                System.out.println("已经是停止状态了,我要退出");
                throw new InterruptedException();
            }
            System.out.println("i = " + (i+1));
        }   
        }catch (InterruptedException e){
            System.out.println("进入InterruptThread的catch块");
            e.printStackTrace();
        }
    }
}
package thread.test;

public class InterruptRun {
	 public static void main(String[] args) {
	        try {
	            InterruptThread threadI = new InterruptThread();
	            threadI.start(); 
	            threadI.interrupt();
	            Thread.currentThread().interrupt();
	            System.out.println("main:" + Thread.currentThread().getName() + "是否停止1? = " + Thread.interrupted());
	            System.out.println("main:" + Thread.currentThread().getName() + "是否停止2? = " + Thread.interrupted());
	            System.out.println(threadI.getName() + "是否停止3? = " + threadI.isInterrupted());
	            System.out.println(threadI.getName() + "是否停止4? = " + threadI.isInterrupted());
	        }catch (Exception e){
	            System.out.println("main catch");
	            e.printStackTrace();
	        }
	    }

}

运行结果:

已经是停止状态了,我要退出
main:main是否停止1? = true
main:main是否停止2? = false
Thread-0是否停止3? = true
Thread-0是否停止4? = true
进入InterruptThread的catch块
java.lang.InterruptedException
    at thread.test.InterruptThread.run(InterruptThread.java:11)

 

因此这interrupted 和isInterrupted 方法有两个主要区别:
1.interrupted 是作用于当前线程,isInterrupted 是作用于调用该方法的线程对象所对应的线程。(线程对象对应的线程不一定是当前运行的线程。例如我们可以在A线程中去调用B线程对象的isInterrupted方法。)
2.这两个方法最终都会调用同一个方法-----isInterrupted( Boolean 参数),,只不过参数固定为一个是true,一个是false;               注意: isInterrupted( Boolean 参数)是isInterrupted( )的重载方法。

 

package thread.test;

public class InterruptRun {
	 public static void main(String[] args) throws InterruptedException {
		 	Thread t = new Thread(new Worker());  
	        t.start();  
	        Thread.sleep(200);  
	        t.interrupt();  
	        System.out.println("Main thread stopped.");  
	    }  
	      
	    public static class Worker implements Runnable {  
	        public void run() {  
	        	System.out.println("Worker started."); 
	            while(true){
		            try {  
		            	if( Thread.currentThread().isInterrupted()){
		            		System.out.println("中断");
		            		break;
		            	}
		            } catch (Exception e) {  
		                System.out.println("Worker IsInterrupted: " +   
		                        Thread.currentThread().isInterrupted());  
		            }  
	            }
	            System.out.println("Worker stopped.");  
	        }  
	    }

}

运行结果:

Worker started.
Main thread stopped.
中断
Worker stopped.

 

package thread.test;

public class InterruptRun {
	 public static void main(String[] args) throws InterruptedException {
		 	Thread t = new Thread(new Worker());  
	        t.start();  
	        Thread.sleep(200);  
	        t.interrupt();  
	        System.out.println("Main thread stopped.");  
	    }  
	      
	    public static class Worker implements Runnable {  
	        public void run() {  
	        	System.out.println("Worker started."); 
	            while(true){
		            try {  
		            	Thread.sleep(2000);
		            } catch (InterruptedException e) {  
		                System.out.println("Worker IsInterrupted: " +   
		                        Thread.currentThread().isInterrupted());  
		            }  
	            }
	        }  
	    }

}

运行结果:

Worker started.
Main thread stopped.
Worker IsInterrupted: false

 

线程被中断后的状态是false的原因:

线程中断仅仅是设置线程的中断状态位,不会停止线程。
所以当一个线程处于中断状态时,如果再由wait、sleep以及jion三个方法引起的阻塞,那么JVM会将线程的中断标志重新设置为false,并抛出一个InterruptedException异常,
然后开发人员可以中断状态位的本质作用-----就是程序员根据try-catch功能块捕捉jvm抛出的InterruptedException异常来做各种处理,比如如何退出线程。

interrupt()是用来设置中断状态的。返回true说明中断状态被设置了而不是被清除了。我们调用sleep、wait等此类可中断(throw InterruptedException)方法时,
一旦方法抛出InterruptedException,当前调用该方法的线程的中断状态就会被jvm自动清除了,就是说我们调用该线程的isInterrupted 方法时是返回false。
如果你想保持中断状态,可以再次调用interrupt方法设置中断状态。这样做的原因是,java的中断并不是真正的中断线程,而只设置标志位(中断位)来通知用户。
如果你捕获到中断异常,说明当前线程已经被中断,不需要继续保持中断位

你可能感兴趣的:(Java并发编程实践笔记,java基础)