jdk线程池

  

 1.状态表示:

        ThreadPoolExecutor 使用 int 的高 3 位来表示线程池状态,低 29 位表示线程数量

状态名
3
接收新任
处理阻塞队列任
说明
RUNNING111  是初始状态
SHUTDOWN000
不会接收新任务,但会处理阻塞队列剩余任务
STOP 001
会中断正在执行的任务,并抛弃阻塞队列任务
TIDYING010--
任务全执行完毕,活动线程为0 即将进入 终结
TERMINATED011--终结状态
        信息存储在一个原子变量 ctl 中,目的是将线程池状态与线程个数合二为一,这样就可以用一次 cas 原子操作 进行赋值。

2.构造方法属性:

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              RejectedExecutionHandler handler) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), handler);
    }
            corePoolSize 核心线程数目 (最多保留的线程数)
            maximumPoolSize 最大线程数目
            keepAliveTime 生存时间 - 针对救急线程
            unit 时间单位 - 针对救急线程
            workQueue 阻塞队列
            threadFactory 线程工厂 - 可以为线程创建时起名
            handler 拒绝策略

        最大线程数量 = 核心数 + 救急数.

处理过程:
        线程池中刚开始没有线程,当一个任务提交给线程池后,线程池会创建一个新线程来执行务。 当核心线程数达到 corePoolSize的初始值而且 没有其他线程空闲,如果这时再加入任务,新加的任务会被加入 阻塞workQueue 队列排队,直到有空闲的线程。 如果队列选择了有界队列,那么任务超过了队列大小时,就会创建救急线程来处理任务(maximumPoolSize - corePoolSize ) 如果队列没有使用有界队列就不会创建救急线程而是采用拒绝策略. 当线程到达 maximumPoolSize 仍然有新任务这时会执行拒绝策略。拒绝策略 jdk 提供了 4 种实现,
        AbortPolicy 让调用者抛出
        RejectedExecutionException 异常,这是默认策略
        DiscardPolicy 放弃本次任务
        DiscardOldestPolicy 放弃队列中最早的任务,本任务取而代之.
   核心线程和救急线程对比:
           1.救急线程是有存活时间的 keepAliveTime ,而核心线程一旦创建就会一直在线程池中.
           2.两者的创建机理是不同的.
3.JDK Executors 类中提供了众多工厂方法来创建各种用途的线程池.

 

        1.newFixedThreadPool :
    public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }
                   核心线程数 == 最大线程数(没有救急线程被创建),因此也无需超时时间
                   阻塞队列是无界的,可以放任意数量的任务.
      2.newCachedThreadPool
   public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }
                特点:核心线程数是 0,最大线程数是 Integer.MAX_VALUE ,救急线程的空闲生存时间是 60s ,意味着 全部都是救急线程( 60s 后可以回收) 队列采用了 SynchronousQueue 实现特点是,它没有容量,没有线程来取是放不进去的.
       3. newSingleThreadExecutor
       
  public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }
     线程数固定为 1 ,任务数多于 1 时,会放入无界队列排队。任务执行完毕,这唯一的线程
也不会被释放。

  3.执行方法:

    
// 执行任务
void execute ( Runnable command );
// 提交任务 task ,用返回值 Future 获得任务执行结果
< T > Future < T > submit ( Callable < T > task );
// 提交 tasks 中所有任务
< T > List < Future < T >> invokeAll ( Collection <? extends Callable < T >> tasks )
throws InterruptedException ;
// 提交 tasks 中所有任务,带超时时间
< T > List < Future < T >> invokeAll ( Collection <? extends Callable < T >> tasks ,
long timeout , TimeUnit unit )
throws InterruptedException ;
// 提交 tasks 中所有任务,哪个任务先成功执行完毕,返回此任务执行结果,其它任务取消
< T > T invokeAny ( Collection <? extends Callable < T >> tasks )
throws InterruptedException , ExecutionException ;
// 提交 tasks 中所有任务,哪个任务先成功执行完毕,返回此任务执行结果,其它任务取消,带超时时间
< T > T invokeAny ( Collection <? extends Callable < T >> tasks ,
long timeout , TimeUnit unit )
throws InterruptedException , ExecutionException , TimeoutException ;

4.关闭线程池

  1.shutdown

 线程池状态变为 SHUTDOWN 不会接收新任务 , 但已提交任务会执行完 此方法不会阻塞调用线程的执行

    

 在调用shutdown之后再执行新的任务就会报错,但是之前的所有任务都会执行:

   

  2.shutdownNow

    线程池状态变为 STOP ,不会接收新任务 会将队列中的任务返回并用 interrupt 的方式中断正在执行的任务

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值