Java 线程池的简单理解

126 阅读4分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 6 天,点击查看活动详情

在开发中频繁的创建销毁线程会导致系统效率降低,在创建和销毁上也会耗费很多时间,那么将引入线程池来对线程进行管理,让线程不再是频繁的创建销毁,而是重复利用。

Java线程池,实际上就是一个可以容纳多个线程的容器,里面的线程可以重复使用,不会频繁的创建和销毁,当有任务需要使用线程来执行的时候,线程池会自动分配里面的线程来执行,替代了传统的创建线程执行的方式。

1. 线程池的好处

  1. 线程被重复利用,降低线程频繁创建销毁的开销。
  2. 线程无需频繁创建,减少系统响应时间,任务不需要等待线程创建才执行。
  3. 增强线程的可管理性,根据实际情况自定义线程池的线程数量,防止线程创建过多导致CPU占用高,程序卡死,使用线程池可以进行统一分配,调优和监控。
  4. 线程池具有可扩展性,允许开发人员自定义扩展功能,例如允许任务延期执行和定期执行。

2. 线程池相关参数

这里贴一张网上看到的源码注释

  • corePoolSize(核心线程数)
    • 线程池中保留的线程数,即没有任务需要执行时的线程大小,并且在工作队列满了的情况下才会创建超出这个数量的线程。
    • 线程池在创建的时候线程不会立即启动,而是有任务提交的时候才会启动。
  • maximumPoolSize(最大线程数)
    • 线程中允许的最大线程数。
    • 线程池中所允许的最大线程数,如果队列中任务已满,并且当前线程个数还未达到最大线程数,那么就会创建新的线程执行任务,否则执行拒绝策略。
    • 在线程池开启期间,可以通过set()方法修改该值。
  • keepAliveTime(线程空闲时间)
    • 该值指的是空闲线程允许存在的时间,当空闲线程存在的时间超过了改值,那么该线程将会被销毁,节省资源。
  • unit(单位)
    • keepAliveTime的时间单位。
  • workQueue(阻塞队列)
    • 决定阻塞任务的排队策略。
  • threadFactory(线程工厂)
    • 自定义线程创建。
    • 当线程池需要创建线程时,就会调用该方法。
  • handler(拒绝策略)
    • 当阻塞队列已经满了,并且线程池中线程数量也达到了最大限制,如果有新任务继续提交进来,则会执行拒绝策略里面的代码。

3. 线程池的具体使用

// 生成一个线程数量为2的线程池
ExecutorService executorService = Executors.newFixedThreadPool(2);
ExecutorService executorService1 = Executors.newFixedThreadPool(2);
Runnable runnable = () -> {
    // 输出所在线程池和所在线程名字以及执行时间
    System.out.println("Thread name: " + Thread.currentThread().getName() +
                       ", Time: " + System.currentTimeMillis());
};

// 调用submit传递线程任务开启线程
executorService.submit(runnable);
executorService.submit(runnable);
executorService.submit(runnable);
executorService1.submit(runnable);
executorService1.submit(runnable);

// shutdown销毁线程池
executorService.shutdown();
executorService1.shutdown();
  • newFixedThreadPool(int var0)
    • 创建固定数目线程的线程池,当任务执行时,若线程池中有空闲线程,则使用空闲线程执行任务,否则任务将进入阻塞队列,直到有空闲线程来执行该任务。
  • submit(Runnable var1)
    • 向线程池中提交任务,若线程池中没有空闲线程,则任务将进入阻塞队列,等待被执行。
    • 其返回的Future对象可以判断传入的runnable是否执行完毕future.isDone()
  • shutdown()
    • 销毁线程池,但该方法销毁线程并不是马上销毁,而是停止线程池在接收提交的新任务,并且已经在线程池的线程并不会强制终止,而是在线程池内所有线程执行完再进行真正的销毁。
  • shutdownNow()
    • 立刻销毁线程池,该方法会移除当前已经提交但还没有执行的任务,停止接收提交的新任务,并尝试立马停止当前正在执行的线程。
    • 停止当前正在执行的线程是不安全的,有可能线程能够被马上停止,但也有可能一直执行到线程任务结束。

如有错误,欢迎在评论区指出!