中断

中断

  一个线程在执行完毕之后会自动结束,如果在运行的过程中发生异常也会提前结束。

1.InterruptedException

  调用一个线程的interrupt()方法来中断该线程,如果该线程处于阻塞有限等待无限等待状态,那么就会抛出InterruptedException,从而提前结束该线程,但是不能中断I/O阻塞和Sychronized锁阻塞

  以下代码,启动一个线程后中断它,由于它调用了sleep()方法,所以处于有限等待状态,那么它就会抛出InterruptedException异常,从而提前结束线程,不再执行后面的语句。

public class InterruptException{
    public static void main(String[]args)throws InterruptedException{
        MyThread thread=new MyThread();
        thread.start();
        thread.interrupt();
        System.out.println("haha");
       
    }

}
class MyThread extends Thread{
    @Override
    public void run(){
    try {
        Thread.sleep(2000);
        System.out.println("Thread run");
    } catch (InterruptedException e) {
        e.printStackTrace();//TODO: handle exception
    }
}
}
haha
java.lang.InterruptedException: sleep interrupted
	at java.base/java.lang.Thread.sleep(Native Method)
	at MyThread.run(InterruptException.java:15)

Process finished with exit code 0

2.interrupted()

​  如果一个线程的run()方法执行一个无限循环,并且没有执行sleep()等会抛出InterruptedException的操作,那么调用interrupt()方法,就无法使线程提前结束。但是调用interrupt()方法会设置线程的中断标记(一旦方法抛出InterruptedException异常,那么jvm就会自动清除中断标记),此时调用interrupted()方法会返回true。因此在循环体中使用interrupted()方法来判断线程是否处于中断的状态,从而提前结线程。

public class InterruptExemple{
    private static class MyThread extends Thread{
        @override
        public void run(){
            while(!interrupted()){
                //...
            }
            System.out.println("Thread end");
        }
    }
    public static void main(String[]args){
        MyThread thread =new MyThread();
        thread.start();
        thread.interrupt();
    }
}
Thread end

3.Executor 的中断操作

  调用Executor的shutdown()方法会等待线程都执行完之后再关闭,但是如果调的是shutdownNow()方法,就相当于调用每个线程的interrupt()方法。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.*;
public class ExecutorInterrupted{
    public static void main(String[]args){
    ExecutorService executorService=Executors.newCachedThreadPool();
    executorService.execute(new MyRunnable());
    executorService.shutdownNow();
    System.out.println("Main run");
    }
}
class MyRunnable implements Runnable{
    public void run(){
        try {
            Thread.sleep(2000);
            System.out.println("Thread run");
        } catch (Exception e) {
           e.printStackTrace(); //TODO: handle exception
        }
    }
}
Main run

pool-1-thread-1正在执行

java.lang.InterruptedException: sleep interrupted

	at java.base/java.lang.Thread.sleep(Native Method)

	at MyRunnable.run(MakeThreadPoll.java:32)

	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)

	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)

	at java.base/java.lang.Thread.run(Thread.java:834)



  如果只想中断Executor中的一个线程,可以通过使用submit()方法来提交一个线程,他会返回Future<?>对象。通过调用该对象的cancel(true)方法就可以中断线程。

Future<?>future=executorService.submit(()->{
    //..
});
future.cancel(true)
原文地址:https://www.cnblogs.com/yjxyy/p/10695256.html