线程池

线程池的优点:

  1、提高资源利用率
    线程池可以重复利用已经创建了的线程
  2、提高响应速度
    因为当线程池中的线程没有超过线程池的最大上限时,有的线程处于等待分配任务状态,当任务到来时,无需创建线程就能被执行。
  3、具有可管理性
    线程池会根据当前系统特点对池内的线程进行优化处理,减少创建和销毁线程带来的系统开销。
  4、有效控制最大并发线程数,提高系统资源利用率,同时也可以避免过多的资源竞争,避免阻塞

  5、提供定时执行、定期执行,单线程、并发数控制等功能

线程池 :- ThreadPoolExecutor

  corePoolSize:核心线程数量

  maximumPollSize:线程最大线程数

  workQueue:阻塞队列,存储等待执行的任务(重要:会对线程池运行过程产生重大影响)

   当线程池中的线程数量小于corePoolSize的时候,直接创建新的线程来处理任务,即是线程池中有空闲的线程;如果线程池中的线程数量大于corePoolSize并且小于maximumPollSize,只有当workQueue阻塞的时候,才去创建新的线程去处理任务;如果设置的corePoolSize和maximumPollSize相同的时候,那么创建的线程池的大小是固定的,此时如果有新的任务提交,如果workQueue未阻塞,则把任务放到workQueue里面,等待空闲线程取出任务执行,如果运行的线程数量大于maximumPollSize并且workQueue已经阻塞,则会有拒绝策略来指定由谁来执行任务;

  keepAliveTime:线程没有任务执行的时候最多保持多久时间终止;

  unit:keepAliveTime的时间单位

  threadFactory:线程工厂,用来创建线程

  rejectHandler:当拒绝处理任务时候的策略

构造一个线程池:

 

 线程池的几种状态:

状态1:runing=>能接受新提交的任务,并且也能处理阻塞队列里面的任务

状态2:shutdown=>属于关闭状态;当一个线程池属于关闭状态时候,不能执行新提交的任务,但是会继续执行阻塞队列里面的任务;如果阻塞队列为空,线程池中的工作线程为空【当running状态线程池指向shutdown()时候进入此状态】

状态3:stop=>不能接受新任务并且也不能处理阻塞队列里面的任务,线程池中的工作线程数量为0;【当running状态线程池指向shutdownNow()时候进入此状态】

状态4:tidying=>所有的任务一终止,工作线程数为0时候进入该状态

状态5:terminated=>tidying状态调用terminated()后进入该状态

执行方法:

方法1:execute()    提交任务交给线程池执行

方法2:submit()    提交任务,能够返回执行结果 execute+Future

方法3:shutdown()  关闭线程池,等地啊任务都执行完

方法4:shutdownNow()  关闭线程池,不等任务执行完

方法5:getTaskCount()   线程池已执行和未执行的任务总数

方法6:getCompleteTaskCount()   已完成的任务数量

方法7:getPoolSize()   线程池当前的线程数量

方法8:getActiveCount()  当前线程池中正在指向任务的线程数量

 

通过Executors封装的的常用的四个线程池:

CachedThreadPool
SingleThreadPool
  总结:这两个线程池的主要问题:堆积的请求处理队列可能会耗费非常大的内存,甚至导致OOM

FixThreadPool
ScheduledThreadPool  
  总结:这两个线程主要问题-> 线程数的最大数是Integer.MAX_VALUE,可能会导致创建数量非常多的线程,甚至OOM

线程池的合理配置:
  CPU密集型任务,就需要尽量压榨CPU,参考值可以设置为NCPU+1
  IO密集型任务,参考值可以设置为2*NCPU

为了更加明确线程池的运行规则,避免资源耗尽的风险,通常通过ThreadPoolExecutor手动创建线程池
ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("demo-%d").build();
        ExecutorService pool = new ThreadPoolExecutor(5, 200,
                0L, TimeUnit.MICROSECONDS,
                new LinkedBlockingDeque<Runnable>(1024), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());
        pool.execute(()-> {
            log.info(Thread.currentThread().getName());
        });
        pool.shutdown();

  

posted @ 2018-10-24 22:56  zlAdmin  阅读(141)  评论(0)    收藏  举报