java多线程——线程池

1.什么是线程池?

juc包下提供了一个java.util.concurrent.Executor接口实现线程池。主要解决处理器单元内多个线程执行的问题,可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力。

2.使用线程池有如下几个优点:

  • 降低资源消耗:通过重复利用已创建的线程降低线程创建与销毁带来的损耗
  • 提高响应速度:当任务到达时,任务可以不需要等待线程创建就能立即执行
  • 提高线程的可管理性:使用线程池可以统一进行线程分配、调度和监控

3.线程池的实现原理:

java多线程——线程池_第1张图片

     当有一个Runnable或者Callable到达时,执行策略如下:

  • 第一步:首先判断核心线程池是否已满,如果未满,将当前任务分配给空闲线程执行;如果已满,执行第二步。
  • 第二步:判断工作队列是否已满,如果工作队列未满,提交任务存储到工作队列中等待核心线程池的调度;如果已满,执行第三步。
  • 第三步:判断当前线程池的线程数是否已经到达最大值maxiumSize,若未到达,继续创建新线程执行此任务;否则,将任务交给饱和策略处理。

3.线程池的使用

3.1手工创建线程池

通过创建ThreadPoolExecutor来创建线程池,方法如下:

    public ThreadPoolExecutor(int corePoolSize,
                              int maxiumSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue workQueue,
                              RejectedExecutionHandler handle )

参数列表中几个参数说明如下:

3.1.1corePoolSize(核心线程池大小):当提交任务到线程池时,线程池会创建一个新的线程来执行任务,即使核心池中有其他空闲线程也会创建线程池,一直到线程数达到了核心池的大小为止。(调用prestartAllCorethreads()线程池会提前创建并启动好所有核心线程)。

3.1.2workQueue(工作队列):用于保存等待执行任务的阻塞队列。有如下几个选择

  • ArrayBlockingQueue:基于数组结构的有界阻塞队列,按照FIFO元原则对元素进行排序
  • LinkedBlockingQueue:基于链表结构的阻塞队列,按照FIFO排序元素,吞吐量高于ArrayBlockingQueue。Executors.newFixedThreadPool()采用此队列
  • SynchronousQueue:一个不存储元素的阻塞队列。每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态,通常吞吐量比LinkedBlockingQueue还要高。Executors.nwCachedThreadPool()采用此队列。
  • PriorityBlockingQueue:具有优先级的无界阻塞队列。

3.1.3maxiumSize(线程池最大线程数量):线程池允许创建的最大线程数。如果队列已满并且已创建的线程数小于此参数,则线程池会创建新的线程执行任务;否则调用饱和策略机制。如果采用无界队列,则此参数无意义。

3.1.4keepAliveTime(线程保持活动时间):线程池的工作线程空闲后,保持存活的时间,若任务很多并且每个任务的执行时间较短,可以调大此参数来提高线程利用率。

3.1.5TimeUnit(线程保持活动时间的单位):天、小时、分、秒、毫秒...

3.1.6RejectedExecutionHandle(饱和策略):当队列和线程池都满了,说明线程池处于饱和状态。此时采用饱和策略来处理任务,默认采用AbortPolicy。JDK内置的四个饱和策略如下

  • AbortPolicy:表示无法处理新任务抛出异常,JDK默认采用此策略
  • CallerRunsPolicy:等待调用者线程空闲后运行任务
  • DiscardOldestPolicy:丢弃阻塞队列中最近的一个任务并执行当前任务
  • DiscardPolicy:不处理,直接将新任务丢弃,也不报错

3.2使用JDK内置的四大线程池

3.2.1 普通调度池

  1. Executors.newCachedThreadPool():缓冲线程池,无大小限制的线程池:适用于很多短期任务的小程序,负载较轻的服务器
  2. Executors.newFixedThreadPool(int nThreads):固定大小线程池:适用于为了满足资源管理的需求而需要限制当前线程数量的应用场合,适用于负载比较重的服务器。
  3. Executors.newSingleThreadPool():单线程池:适用于需要保证顺序执行的各个任务,并且在任意时间点,不会有多个线程活动的场景。

3.2.2 定时调度池

Executors.newScheduledThreadPool(time):用于在给定的延迟之后运行任务或者定期执行任务。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(java,多线程,线程池,java语言)