java thread pool

当创建线程和销毁线程的时间远大于线程执行任务的时间,就可以考虑用线程池来提升性能。合理利用线程池能够带来三个好处。第一:降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。第二:提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行,即在处理任务前的准备阶段,程序的开始阶段就准备好线程池。第三:提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。

SingleThreadExecutor:单个后台线程 (其缓冲队列是LinkedBlockingQueue,无界的)。此线程池保证所有任务的执行顺序按照任务的提交顺序执行.

scheduledThreadPool(int corePoolSize,maximumPoolSize(Integer.Max_Value))

创建一个线程池,它可以安排任务在给定时间的延迟之后运行该命令,或定时执行。

cachedThreadPool : corePoolSize(0),maximumPoolSize(Integer.Max_Value),workQueue(synchronousQueue)

创建一个线程池,根据需要创建新线程,但是将重写之前线程池的构造。

这个线程池通常会提高性能去执行许多短期异步任务的程序。

如果有可用线程,当线程池调用execute, 将重用之前的构造函数。

如果没有现有的线程可用,那么就创建新的线程并添加到池中。

线程没有使用60秒的时间被终止并从线程池里移除缓存。

因此,一个闲置时间足够长的线程池不消耗任何资源。

注意,线程池有类似的属性,但有一些不同的细节(例如,超时参数)可以使用@link ThreadPoolExecutor构造函数创建。

fixedThreadPool : corePoolSize(n),maximumPoolSize(n),workQueue(linkedBlockingQueue)

创建一个线程池,使用固定数量的线程在共享的无界队列中操作。

在任何时候,有最多  nThreads(就是我们传入参数的数量)的线程将处理任务。

如果所有线程都处于活动状态时,提交额外的任务,他们会在队列中等待,直到有一个线程可用。

如果在执行过程中出现故障,任何线程都会终止。如果需要执行后续任务,新的任务将取代它的位置。线程池中的线程会一直存在,直到它显式为止(调用shutdown)

nThreads 就是传入线程池的数量  ,当nThreads  <= 0 就会抛异常IllegalArgumentException

  • LinkedBlockingQueue:基于链表的先进先出队列,如果创建时没有指定此队列大小,则默认为Integer.MAX_VALUE;
  • synchronousQueue:这个队列比较特殊,它不会保存提交的任务,而是将直接新建一个线程来执行新来的任务。

corePoolSize():核心池,有两个方法preStartCoreThread和preStartAllCoreThread,默认建好的线程池初始线程为0, 只有调用了preStart才会建好初始的线程,不然就是当有任务来之后,才会创建一个线程去执行任务,当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到缓存队列当中。

execute()向线程池提交一个任务。

这个任务可能是直接调用addWorker或放入workQueue中。

 If we cannot queue task, then we try to add a new
* thread.  If it fails, we know we are shut down or saturated
* and so reject the task.

当workQueue也容不下这么多任务时,会尝试继续加线程,失败即reject这个task。

worker的run()会在执行完firstTask后,一直去workQueue中getTask并执行这个task。

submit()这个方法也是用来向线程池提交任务的,但是它和execute()方法不同,它能够返回任务执行的结果,去看submit()方法的实现,会发现它实际上还是调用的execute()方法,只不过它利用了Future来获取任务执行结果

shutdown()和shutdownNow()是用来关闭线程池的。

 

1:如果线程数量未达到corePoolSize,则新建一个线程(核心线程)执行任务

2:如果线程数量达到了corePools,则将任务移入队列等待

3:如果队列已满,新建线程(非核心线程)执行任务

4:如果队列已满,总线程数又达到了maximumPoolSize,就会由RejectedExecutionHandler抛出异常

 

  • 如果当前线程池中的线程数目小于corePoolSize,则每来一个任务,就会创建一个线程去执行这个任务;
  • 如果当前线程池中的线程数目>=corePoolSize,则每来一个任务,会尝试将其添加到任务缓存队列当中,若添加成功,则该任务会等待空闲线程将其取出去执行;若添加失败(一般来说是任务缓存队列已满),则会尝试创建新的线程去执行这个任务(cachedThreadPool走这来达到每来一个任务,建一个线程。但若有旧的线程回收,就会在前面的尝试添加到任务缓存队列时成功添加,并立马被回收的线程执行);
  • 如果当前线程池中的线程数目达到maximumPoolSize,则会采取任务拒绝策略进行处理;
  • 如果线程池中的线程数量大于 corePoolSize时,如果某线程空闲时间超过keepAliveTime,线程将被终止,直至线程池中的线程数目不大于corePoolSize;如果允许为核心池中的线程设置存活时间,那么核心池中的线程空闲时间超过keepAliveTime,线程也会被终止。非核心线程keepAliveTime:cachedThreadPool是60s,fixedThreadPool是0s.

你可能感兴趣的:(java thread pool)