线程池

线程池

线程池主要是控制运行线程的数量,处理过程中将任务放入队列,然后在线程创建后启动这些任务,如果线程数超过了最大数量,超出的线程排队等候,等待其它线程执行完毕,再从队列中取出任务来执行。

为什么要用线程池:

  • 降低资源的消耗,复用已经创建的线程,降低线程的创建和销毁要销毁的资源
  • 提高响应速度,当任务到达时,任务不需要等到线程创建就立即执行
  • 提高线程的可管理性,线程是一种稀缺资源,如果无限制的创建,消耗系统资源,利用线程池可以进行统一的分配和调优,监控。

线程池的种类

newFixedThreadPool:固定线程数量

1
2
3
4
5
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}

newCachedThreadPool:一池n线程,根据请求的任务创建,如果当前没有线程处理新来的请求任务,则创建新的线程

1
2
3
4
5
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}

newSingleThreadExecutor:一池单线程

1
2
3
4
5
6
publicstatic ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}

newScheduledThreadPool:

1
2
3
4
public ScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
new DelayedWorkQueue());
}

线程池的7个参数:

  • corePoolSize:线程池中的常驻核心线程数
  • maximumPoolSize:线程池能够同时容纳执行的最大线程数
  • keepAliveTime:多余的空闲线程的存活时间
  • unit:keepAliveTime的单位
  • workQueue:任务队列,被提交但尚未被执行的任务
  • threadFactory:表示生成线程池工作线程的线程工厂,用于创建线程,一般用默认的即可
  • handler:拒绝策略,表示当队列满了并且线程大于等于线程池的最大线程数

线程池的工作机制

  1. 在创建了线程池后,等待提交过来的任务请求
  2. 当调用executor()方法添加一个请求任务时,线程池会做一些判断
    • 如果当前运行的线程数量小于corePoolSize,那么马上创建线程运行这个任务
    • 如果当前运行的线程数量大于corePoolSize,那么当前任务会加入队列
    • 如果当前队列满了,线程数量小于maximumPoolSize,那么还是要创建非核心线程立刻运行这个任务
    • 如果当前队列满了线程数量大于maximumPoolSize,那么线程胡启动拒绝策略
  3. 当一个线程完成时,会从队列中取下一个任务来执行
  4. 当一个线程空闲,并且超过一定的时间keepAliveTime时,线程池会判断,如果当前的线程数大于corePoolSize,那么这线程就被停掉
  5. 所以线程池的所有任务完成后最终会收缩到corePoolSize的大小

拒绝策略

  • AbortPolicy(默认):直接抛出RejectedExecutionExecution异常阻止系统正常运行
  • CallerRunsPolicy:调用者调节机制,不会抛弃任务,也不会抛出异常,而是将某些任务回退到调用者
  • DiscardOldestPolicy:抛弃任务队列中等待最久的任务,然后把当前任务加入队列中尝试再次提交当前任务
  • DiscardPolicy:直接丢弃任务

自定义线程池

1
2
3
4
5
6
7
ExecutorService es = new ThreadPoolExecutor(2, 5, 2l, TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(3),Executors.defaultThreadFactory(),new ThreadPoolExecutor. AbortPolicy() );
for(int i=0;i<8;i++) {
es.execute(()->{
System.out.println(Thread.currentThread().getName());
});
}
文章目录
  1. 1. 线程池
|
载入天数...载入时分秒...