java基础之线程池

一、线程池:提前创建多个线程存放到集合容器中,其中的线程可以反复使用,减少资源的开销
作用就是:线程执行完一个任务,并不被销毁,而是可以继续执行其他的任务

使用线程池中线程对象的步骤:
1. 创建线程池对象。
2..创建Runnable接口子类对象(线程所要执行的任务【target】)
3. 提交Runnable接口子类对象。

  public class ExecutorTest {
      /**
       * 一个线程池,2个线程,3个任务 Executors:线程池工具类(一个任务对应一个线程)
        ThreadPoolExecutor底层实现是用非阻塞机制
       * @param args
       */
      public static void main(String[] args) {
          ExecutorService executorService = Executors.newFixedThreadPool(2);
          executorService.submit(new RunableDemo());
          executorService.submit(new RunableDemo());
          executorService.submit(new RunableDemo());
      }
  }

二、创建线程池的5种方式:可缓存、定时、定长、单列、抢占

  1:创建单核心的线程池
  ExecutorService executorService = Executors.newSingleThreadExecutor();
  作用:线程池中使用的从始至终都是单个线程,所以这里的线程名字都是相同的,而且下载任务都是一个一个的来,直到有空闲线程时,
  才会继续执行任务,否则都是等待状态。

  2:创建固定核心数的线程池,这里核心数 = 2
  ExecutorService executorService = Executors.newFixedThreadPool(2);
  作用:两个线程执行任务可以同时进行,并且所用的线程数量始终都只有两个,因为它的最大线程数等于核心线程数,线程存活时间都是无限的,
  不会再去创建新的线程了
  
  3:创建一个自动增长的线程池
  ExecutorService executorService = Executors.newCachedThreadPool();
  作用:没有核心线程数,但是我们的最大线程数没有限制,所以一点全部开始下载,就会创建出 5 条新的线程同时执行任务,从上图的例子看出,
  每天线程都不一样

  4:创建一个具有抢占式操作的线程池
  ExecutorService executorService = Executors.newWorkStealingPool();
  作用:可以看出WorkStealingPool这个方法会以当前机器的CPU处理器个数为线程个数,这个线程池会并行处理任务,且不保证顺序,
  同时并发数能作为参数设置,而任务如果想要都执行就要设置和任务数量对应的并发数。

三、源码代码分析:

当任务数<核心线程数时,任务由核心线程执行

当任务数>核心线程数&&任务数<阻塞队列长度时,任务由核心线程执行

当任务数>阻塞队列长度时,需要创建新线程(n),但核心线程数 + n不能大于最大线程数

posted @ 2020-07-23 00:30  jock_javaEE  阅读(137)  评论(0)    收藏  举报