Java 线程 Interrupt() 方法解析

匿名 (未验证) 提交于 2019-12-02 21:53:52
Java中我们可以通过一些手段关闭一个线程。关闭一个线程有两种方式:一种是强制关闭,比如说是exit退出当前线程,stop()方法强制关闭一个线程,Interrupt方法给一个线程打上标识,如果遇到阻塞的情况下抛出InterruptedException 结束线程。

其中使用stop方法的方式强制关闭线程的方式已经不推荐了,因为可能导致一些难以预料的后果,并且这些方法在新版本的Java API中已经标注为将要过期。现在一般使用Interrupt方法的方式来关闭线程。


Java Interrupt() 方法没法强制关闭一个线程,能够做的是给线程设置中断标志。
对于处于阻塞状态的线程调用interrupt()方法的时候,会抛出一个InterruptException,并且结束线程的等待状态,直接跳转到异常处理的代码块
也就是说,Interrupt方法可以结束处于阻塞状态的线程(比如调用sleep,join,wait方法而阻塞的线程)




我的代码和我的日志

代码:
 
import java.util.Date;  
  
public class InterrupteTest {  
    private static Object lock = new Object();  

    public static void main(String[] args) {  
        // 测试线程调用sleep方法时被执行Interrupt  
        // 线程会被成功结束掉  
        Thread t1 = new Thread(() -> {  
            try {  
                Thread.sleep(10000);  
            } catch (Exception e) {  
                System.out.println("Thread1 is interrupted " + new Date().toString());  
            }  
        });  
  
        // 测试当一个线程处于wait状态时,被外部线程调用Interrupt方法  
        // 线程如果处于wait状态会被成功地结束掉  
        Thread t2 = new Thread(() -> {  
            try {  
                syncMethod();  
            } catch (Exception e) {  
                System.out.println("Thread2 is interrupted " + new Date().toString());  
            }  
        });  
        // 测试一个线程调用自己本身的interrupt()方法 -- 在线程阻塞之前调用  
        // 可以成功的把当前线程给结束掉  
        Thread t3 = new Thread(() -> {  
            try {  
                Thread.currentThread().interrupt();  
                syncMethod();  
            } catch (InterruptedException e) {  
                System.out.println("Thread3 is interrupted" + new Date().toString());  
            }  
        });  
  
        // 测试一个线程调用自己本身的interrupt()方法 -- 在线程阻塞之后调用  
        // Interrupt方法执行时,当前线程已经退出了阻塞状态,所以对当前线程没有影响  
         Thread t4 = new Thread(() -> {  
            try {  
                syncMethod();  
                Thread.currentThread().interrupt();  
  
            } catch (InterruptedException e) {  
                System.out.println("Thread4 is interrupted" + new Date().toString());  
            }  
        });  
  
        System.out.println("begin interrupt Thread1 " + new Date().toString());  
        t1.setName("Thread1");  
        t1.start();  
        t1.interrupt();  
  
        System.out.println("begin interrupt Thread2 " + new Date().toString());  
        t2.setName("Thread2");  
        t2.start();  
        t2.interrupt();  
  
        System.out.println("begin interrupt Thread3 " + new Date().toString());  
        t3.setName("Thread3");  
        t3.start();  
  
        System.out.println("begin interrupt Thread4 " + new Date().toString());  
        t4.setName("Thread4");  
        t4.start();  
  
    }  
  
    private static void syncMethod() throws InterruptedException {  
        synchronized (lock) {  
            System.out.println(Thread.currentThread().getName() + " is calling syncMethod " + new Date().toString());  
            lock.wait(10000);  
        }  
    }  
}  

日志:
begin interrupt Thread1 Tue Jun 19 18:01:54 CST 2018
begin interrupt Thread2 Tue Jun 19 18:01:54 CST 2018
Thread1 is interrupted Tue Jun 19 18:01:54 CST 2018
begin interrupt Thread3 Tue Jun 19 18:01:54 CST 2018
Thread2 is calling syncMethod Tue Jun 19 18:01:54 CST 2018
begin interrupt Thread4 Tue Jun 19 18:01:54 CST 2018
Thread2 is interrupted Tue Jun 19 18:01:54 CST 2018
Thread4 is calling syncMethod Tue Jun 19 18:01:54 CST 2018
Thread3 is calling syncMethod Tue Jun 19 18:01:54 CST 2018
Thread3 is interruptedTue Jun 19 18:01:54 CST 2018


对上面的代码的总结:
从上面的代码中可以看到的是

        1:sleep和wait方法等待的线程都可以被Interrupt掉

        2:如果一个线程自己调用自己的Interrupt方法的话,最好是在阻塞之前(在本示例代码中就是要在调用wait方法之前),因为当线程阻塞掉之后就没法继续执行逻辑。必须在线程等待之前就把线程状态标识为interrupted状态。



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!