关闭一个线程或线程池使用什么方法最合适?

1.停止一个线程什么方法?

     interceptor:中断线程.不能用stop()方法,非常不安全
      在介绍线程池关闭之前,先介绍下Thread的interrupt。
      在程序中,我们是不能随便中断一个线程的,因为这是极其不安全的操作,我们无法知道这个线程正运行在什么状态,它可能持有某把锁,强行中断可能导致锁不能释放的问题;或者线程可能在操作数据库,强行中断导致数据不一致混乱的问题。正因此,JAVA里将Thread的stop方法设置为过时,以禁止大家使用。
      一个线程什么时候可以退出呢?当然只有线程自己才能知道。
所以我们这里要说的Thread的interrrupt方法,本质不是用来中断一个线程。是将线程设置一个中断状态。
当我们调用线程的interrupt方法,它有两个作用:
      1、如果此线程处于WAITING状态,并抛出InterruptedException异常,线程就可以通过捕获InterruptedException来做一定的处理,然后让线程退出。而处于BLOCKED状态的线程不会抛出异常.关闭不了.
      2、如果此线程正处于RANNABLE状态,则线程不受任何影响,继续运行,仅仅是线程的中断标记被设置为true。所以线程要在适当的位置通过调用isInterrupted方法来查看自己是否被中断,并做退出操作。

举例:LeedCode多线程1195题.
链接:LeedCode多线程交替打印字符串
      在如下题目中,其他线程(打印字母的线程)在调用acquire()方法后,如果获取不到信号量就会进入WAITING状态,并且永远在等待,线程不会结束,所以在主线程(打印普通数字的线程)执行完条件后,需要将等待的线程一一进行中断,然后捕获异常,程序正常退出.

class FizzBuzz {
    private int n;
    
    public FizzBuzz(int n) {
        this.n = n;
    }
    Semaphore fizzSemaphore=new Semaphore(0);
    Semaphore buzzSemaphore=new Semaphore(0);
    Semaphore fizzbuzzSemaphore=new Semaphore(0);
    BlockingQueue<Thread> threadQueue = new LinkedBlockingQueue<>(1);
    ArrayList<Thread> threadList=new ArrayList<>(3);
    
    // printFizz.run() outputs "fizz".
    public void fizz(Runnable printFizz) throws InterruptedException {
        
        threadList.add(Thread.currentThread());
        for(;;){
            try{
                fizzSemaphore.acquire();    
            }catch(InterruptedException e){
                break;
            }
            printFizz.run();
            LockSupport.unpark(threadQueue.poll());    
        }
    }

    // printBuzz.run() outputs "buzz".
    public void buzz(Runnable printBuzz) throws InterruptedException {
        threadList.add(Thread.currentThread());
        for(;;){
            
            try{
                buzzSemaphore.acquire();
            }catch(InterruptedException e){
                break;
            }
            printBuzz.run();
            LockSupport.unpark(threadQueue.poll());    
        }
    }

    // printFizzBuzz.run() outputs "fizzbuzz".
    public void fizzbuzz(Runnable printFizzBuzz) throws InterruptedException {
        threadList.add(Thread.currentThread());
        for(;;){
            try{
                fizzbuzzSemaphore.acquire();
            }catch(InterruptedException e){
                break;
            }
            printFizzBuzz.run();
            LockSupport.unpark(threadQueue.poll());    
        }
    }

    // printNumber.accept(x) outputs "x", where x is an integer.
    public void number(IntConsumer printNumber) throws InterruptedException {
         for(int i=1;i<=n;i++){
            if(i % 3!=0 && i % 5!=0){
                printNumber.accept(i);
            }else if(i % 3==0 && i % 5 !=0){
                threadQueue.put(Thread.currentThread());
                fizzSemaphore.release();
                LockSupport.park();
            }else if(i % 3!=0 && i % 5 ==0){
                threadQueue.put(Thread.currentThread());
                buzzSemaphore.release();
                LockSupport.park();
            }else{
                threadQueue.put(Thread.currentThread());
                fizzbuzzSemaphore.release();
                LockSupport.park();
            }
        }
        //将其他在WAITING状态的线程强制结束
        for(int i=0;i<threadList.size();i++){
            Thread curThread=threadList.get(i);
            curThread.interrupt();
        }
    }
    
}
2.关停线程池用什么方法?,那正在运行的线程怎么办?

关闭线程池有两个方法:
     showdown:按顺序关闭已提交任务的线程,同时不允许提交新的任务.会把所有已经提交的任务执行完再关闭.推荐使用该方法.
      showdownNow:尝试立即关闭所有的线程,一旦执行完当前任务就会被关闭,而新提交的任务不会被执行.
      其内部调用interrupt方法.但是不保证能够关闭所有线程,比如说不能对intertupt做出正确响应的线程.对于那些sleep的线程会抛出中断异常.整个程序终止.处于block状态的线程不会抛出异常.关闭不了.同时移除正在等待的任务.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员bling

义父,感谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值