中断
中断
一个线程在执行完毕之后会自动结束,如果在运行的过程中发生异常也会提前结束。
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)
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号