Java多线程之线程池

时间:2021-10-16 16:20:52

  现在是多核的时代,面向多核的编程很重要,因此基于java的并发和多线程开发非常重要。

  线程池是于队列密切相关的,其中队列保存了所有等待执行的任务。工作者线程的任务很简单:从队列中获取一个任务,执行任务,然后返回线程池,等待下一个任务。

  在线程池中执行任务,比为每一个任务分配一个线程优势更多:

    1.通过重用现在的线程,而不是创建线程,可以在处理多个请求时避免在线程的创建和销毁上的开销。

    2.当请求到达时,工作线程通常已经存在,因此不会犹豫等待创建线程而延迟任务的执行,从而提高响应。

    3.通过适当的调整线程池的大小,可以创建足够多的线程使处理器保持忙碌状态,同时也可以防止过多线程竞争资源而使应用程序的内存耗尽或失败。

  1.配置ThreadPoolExecutor

    类库提供了一个灵活的线程池以及一些有用的默认配置,可以通过调用Executors中的静态工厂方法来创建:

      newFixedThreadPool:创建一个固定长度的线程池,没提交一个任务就创建一个线程,直到到达线程池的最大数量,这时线程池的规模将不再变化。

      newCachedThreadPool:创建一个可缓存的线程池,如果线程的当前规模超过处理的需求时,将回收空闲线程,当需求增加时候,可以添加新的线程,线程池的规模不存在任何限制(不建议使用,如果处理量过多,会因为创建过多线程导致资源耗尽)

      newSingleThreadPool: 是一个单线程的Executor。

      newScheduledThreadPool:创建一个固定长度的线程池,而且以延迟或者定时的方式来执行。

  如果默认的执行策略不满足要求,那么可以通过ThreadPoolExecutor的构造函数来实例化一个对象,并根据自己的需求来定制:

  

/**
* Creates a new {@code ThreadPoolExecutor} with the given initial
* parameters.
*
* @param corePoolSize the number of threads to keep in the pool, even
* if they are idle, unless {@code allowCoreThreadTimeOut} is set
* @param maximumPoolSize the maximum number of threads to allow in the
* pool
* @param keepAliveTime when the number of threads is greater than
* the core, this is the maximum time that excess idle threads
* will wait for new tasks before terminating.
* @param unit the time unit for the {@code keepAliveTime} argument
* @param workQueue the queue to use for holding tasks before they are
* executed. This queue will hold only the {@code Runnable}
* tasks submitted by the {@code execute} method.
* @param threadFactory the factory to use when the executor
* creates a new thread
* @param handler the handler to use when execution is blocked
* because the thread bounds and queue capacities are reached
* @throws IllegalArgumentException if one of the following holds:<br>
* {@code corePoolSize < 0}<br>
* {@code keepAliveTime < 0}<br>
* {@code maximumPoolSize <= 0}<br>
* {@code maximumPoolSize < corePoolSize}
* @throws NullPointerException if {@code workQueue}
* or {@code threadFactory} or {@code handler} is null
*/
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)

其中corePoolSize为线程池的基本大小,maximumPoolSize为最大大小。RejectedExecutionHandler为饱和策略,当有界队列被填满之后,采用什么方式来处理。有四种处理方式

Java多线程之线程池

 

 如果项目中使用Spring,可以使用spring提供的的线程池管理的包装类ThreadPoolTaskExecutor,它对标准的java.util.concurrent.ThreadPoolExecutor进行了封装,配置和使用比较简单

  

<bean id="threadPool"
class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="5" />
<property name="maxPoolSize" value="10" />
<property name="keepAliveSeconds" value="5" />
<property name="queueCapacity" value="2000" />
<property name="rejectedExecutionHandler">
<bean class="java.util.concurrent.ThreadPoolExecutor$AbortPolicy" />
</property>
</bean>

corePoolSize:核心线程数,默认为1

maxPoolSize:最大线程数,默认为Integer.MAX_VALUE

keepAliveSeconds:线程池维护线程所允许的空闲时间,默认为60s

queueCapacity:队列最大长度,默认为Integer.MAX_VALUE

rejectedExecutionHandler:线程池对拒绝任务(超过待处理队列长度)的处理策略

AbortPolicy:表示直接抛出RejectedExecutionException异常  

使用:

threadPool.execute(new Runnable() {
  public void run() {
    try{
    ......
    }catch(Exception e){
    ......
    }
  }
});