• java并发编程笔记(七)——线程池


    java并发编程笔记(七)——线程池

    • new Thread弊端
      • 每次new Thread新建对象,性能差
      • 线程缺乏统一管理,可能无限制的新建线程,相互竞争,有可能占用过多系统资源导致死机或者OOM
      • 缺少更多功能,如更多执行、定期执行、线程中断
    • 线程池的好处
      • 重用存在的线程,减少对象创建、消亡的开销,性能佳
      • 可有效控制最大并发线程数,提高系统资源利用率,同时可以避免过多资源竞争,避免阻塞
      • 提供定时执行、定期执行、单线程、并发数控制等功能

    ThreadPoolExecutor

    重要核心参数

    • corePoolSize:核心线程数量

    • maximuPoolSize:线程池最大线程数

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

    • keepAliveTime:线程没有任务执行的时候最多保持多久时间终止,比如任务量低于核心线程数的时候,线程需要再等待多久才可以释放掉线程

    • unit:keepAliveTime的时间单位

    • threadFactory:线程工厂,用来创建线程,能够使创建的线程具有相同的优先级,并且是非守护的线程,同时也设置了线程的名称,

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

      • 直接抛出异常
      • 用调用者所在的线程来执行任务
      • 丢弃队列中最靠前的任务来释放线程执行当前任务
      • 直接丢弃当前任务

    线程池的五种状态

    • RUNNING:能够接受新提交的任务,也能处理阻塞队列中的任务,

    • (pool.shutdown())SHUTDOWN:关闭状态,不能接受新提交的任务,但是能够处理阻塞队列中保存的任务

    • (pool.shutdownNow())STOP:不能接受新的任务,也不能处理阻塞队列中的任务,会中断正在处理中的线程。

    • TIDYING:阻塞队列为空,线程池中的工作线程数为0

    • (pool.terminated()) TERMINATED

    线程池的相关方法

    • execute():提交任务,交给线程池执行

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

    • shutdown():关闭线程池,等待任务都执行完

    • shutdownNow():关闭线程池,不等待任务执行完

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

    • getCompletedTaskCount():已完成的任务数量

    • getPoolSize():线程池当前的线程数量

    • getActiveCount():当前线程池中正在执行任务的线程数量

    Executor框架接口

    • Executors.newCachedThreadPool

    • Executors.newFixedThreadPool

    • Executors.newScheduledThreadPool

      @Slf4j
      public class ThreadPoolExample4 {
      
          public static void main(String[] args) {
      
              ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
      
      //        executorService.schedule(new Runnable() {
      //            @Override
      //            public void run() {
      //                log.warn("schedule run");
      //            }
      //        }, 3, TimeUnit.SECONDS);
      
              executorService.scheduleAtFixedRate(new Runnable() {
                  @Override
                  public void run() {
                      log.warn("schedule run");
                  }
              }, 1, 3, TimeUnit.SECONDS);
      //        executorService.shutdown();
      
              Timer timer = new Timer();
              timer.schedule(new TimerTask() {
                  @Override
                  public void run() {
                      log.warn("timer run");
                  }
              }, new Date(), 5 * 1000);
          }
      }
      
    • Executors.newSingleThreadExecutor

    线程池的合理配置

    • CPU密集型任务,就需要尽量压榨CPU,参考值可以设置为N(cpu) + 1
    • IO密集型任务,参考值可以设置为2*N(cpu)
  • 相关阅读:
    链表操作
    51nod1085-----01背包
    51nod1046快速幂取余
    51nod贪心算法入门-----任务分配问题
    51nod动态规划-----矩阵取数
    51nod贪心算法入门-----独木舟问题
    POJ2255二叉树
    POJ1182并查集
    POJ1384完全背包问题
    20162313_苑洪铭_ 第7周学习总结
  • 原文地址:https://www.cnblogs.com/xujie09/p/11703686.html
Copyright © 2020-2023  润新知