• 中断


    中断

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

    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)
    
  • 相关阅读:
    linux下的shell 快捷键
    Python3.x和Python2.x的区别
    [Python2.x] 利用commands模块执行Linux shell命令
    redis缓存策略
    高并发解决方案
    java8 lambda表达式应用
    java读写分离的实现
    数据库读写分离
    大数据量处理方案:分布式数据库
    google的CacheBuilder缓存
  • 原文地址:https://www.cnblogs.com/yjxyy/p/10695256.html
Copyright © 2020-2023  润新知