线程池:生命周期

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/y3over/article/details/87993045

一.Executor生命周期

1.线程池有运行、关闭、停止、结束四种状态,结束后就会释放所有资源

2.shutdown 与 shutdowNow 分别对应

  • 平缓关闭:已经启动的任务全部执行完毕,同时不再接受新的任务 
  • 立即关闭:取消所有正在执行和未执行的任务

3.检测线程池是否正处于关闭中,使用isShutdown()

       描述的是非RUNNING状态,也就是SHUTDOWN/STOP/TERMINATED三种状态

4.检测线程池是否已经关闭使用isTerminated()

       描述的是关闭状态,也就是TERMINATED三种状态

5.定时或者永久等待线程池关闭结束使用awaitTermination()操作

        shutdown 与 shutdowNow不是阻塞操作,只是发起关闭任务,awaitTermination则是等待到线程isTerminated()

二.任务生命周期

   任务定义了7种状态:   

  • NEW:新建
  • COMPLETING:完成
  • NORMAL:正常运行
  • EXCEPTIONAL:异常退出
  • CANCELLED:任务取消
  • INTERRUPTING:线程中断中
  • INTERRUPTED:线程已中断

   在这七种状态中,有四种任务终止状态:NORMAL、EXCEPTIONAL、CANCELLED、INTERRUPTED。

   以下为7种状态的关系情况

  1. NEW—>COMPLETING—>NORMAL(任务执行正常)
  2. NEW—>COMPLETING—>EXCEPTIONAL(任务执行异常)
  3. NEW—>CANCELLED(等待任务的取消)
  4. NEW—>INTERRUPTING—>INTERRUPTED(执行中任务的取消)

JAVA中,Future 表示了一个任务的生命周期。

        Future.get()

如果任务正常执行,则返回任务结果

如果任务执行异常,则会抛出执行异常

如果任务被取消,则抛出取消异常(末执行任务直接不执行,正在执行任务中断)

中断正在执行的任务

          采用interrupt()。对线程设置为中断标志。设置后不会立刻中断线程,而是待调用严格检查异常interruptException的时候就会停止,比如await,sleep等。
然而,并不是所有的阻塞都会响应中断,对于不能响应中断interruptException的阻塞。interrupt方法只能标志位可中断,但是无任何其他的作用。处理不可中断的阻塞 ,我们应该查找阻塞的原因,然后重写interrupt的方法来中断。

1.io包中的socket I/O:阻塞I/O形式为对套接字的read、write操作。虽然read,write操作不会响应中断,但是通过关闭底层的套接字,可以使得由于使用该方法而阻塞的线程抛出socketException
2.io包中的同步I/O 
3.selector的异步IO,close或wakeup的时候会使线程抛出CloseSelectorException
4.获得某个锁:如果一个线程因等待某个锁而阻塞,那么该线程是不会理会中断,唯一的办法是使用实现lock接口的reentrantlock(注释3)对象
(具体参考JAVA并发编程实战)

 Future的灵活运用 

    等待一任务超过一定时间则取消它

public  static  void timeRun(Runnable r, long timeout, TimeUnit unit){
        ExecutorService executor = Executors.newSingleThreadExecutor();

        Future task = executor.submit(r);

        try {
            task.get(timeout, unit);
        } catch (InterruptedException e) {
            //中断取消
        } catch (ExecutionException e) {
            //执行异常
        } catch (TimeoutException e) {
           //超时
        }finally {
            //如果任务超时,则直接取消,结果已没作用
            task.cancel(true);
            //true 不管任务是否执行,可以中断。false:如果任务还未执行,就不要运行。
        }
    }

猜你喜欢

转载自blog.csdn.net/y3over/article/details/87993045