线程池

线程池

为什么要使用线程池

线程是不是越多越好?

  1. 线程在java中是一个对象,更是操作系统的资源,线程创建,销毁需要时间。如果创建时间+销毁时间>执行任务时间 就很不合适了。
  2. java对象占用堆内存,操作系统线程占用系统内存,根据jvm规范,一个线程默认最大栈大小1M,这个栈空间是需要从系统内存中分配的。线程过多,会消耗很多内存。
  3. 操作系统需要平凡切换线程上下文,影响性能。
    总结:线程池的推出就是为了方便控制线程数量。

线程池组成部分

  1. 线程池管理器(ThreadPool):用于创建并管理线程池,包括 创建线程池,销毁线程池,添加新任务;
  2. 作线程(PoolWorker):线程池中线程,在没有任务时处于等待状态,可以循环的执行任务;
  3. 务接口(Task):每个任务必须实现的接口,以供工作线程调度任务的执行,它主要规定了任务的入口,任务执行完后的收尾工作,任务的执行状态等;
  4. 任务队列(taskQueue):用于存放没有处理的任务。提供一种缓冲机制。

线程池API

接口定义和实现类

线程池

方法定义

ExecutorService

线程池

ScheduledExecutorService

public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit);
public ScheduledFuture schedule(Callable callable, long delay, TimeUnit unit);
这两个方法创建并执行一个一次性任务,过了延迟时间就会执行

public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit);线程池
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit);
线程池

线程池创建方式–Executors工具类

  1. newSingleThreadExecutor():
    只有一个线程来执行无界任务队列的单一线程池。该线程池确保任务按加入的顺序一个一个的依次执行。当唯一的线程因异常中止时,将创建一个新的线程来继续执行后续任务,与new FixedThreadPool(1)的区别在于,单一线程池的池大小在new SingleThreadExecutor()方法中是硬编码,不可更改。
  2. newCachedThreadPool():
    创建一个大小无界的缓冲线程池。它的任务队列是一个同步队列(SynchronousQueue)。任务加入到池中,如果池中有空闲线程,则用空闲线程,如无则创建新线程执行。池中线程空闲超过60秒,将会北销毁释放。线程数随任务的多少变化,适用于执行耗时较小的异步任务。池的核心线程数=0,最大线程数=Integer.MAX_VALUE。
  3. newFixedThreadPool(int nThreads):
    创建一个固定大小,任务队列容量无界的线程池。核心线程数=最大线程数。
  4. newScheduledThreadPool(int corePoolSize):
    能定时执行任务的线程池,该池的核心线程数由参数指定,最大线程数=Integer.MAX_VALUE。

通过ThreadPoolExecutor创建

ThreadPoolExecutor():
是最原始的线程池创建,上面1-3创建方式都是对ThreadPoolExecutor的封装。

后续讲解线程池使用及线程池的拒绝策略