java 线程池的原理分析

来源:互联网 发布:奇门排盘软件下载 编辑:程序博客网 时间:2024/06/01 07:27
笔者最近最近几个晚上都在总结线程池,看了很多博客,之前有些地方不明白,现在总算是明白线程池的原理了。我总结了一下,分享给大家,若有不妥的地方还望读者指出,非常感谢您的指点。

    首先得明白线程池是什么,干什么的?
        通俗一点的理解就是一些线程的集合。当收到一个任务后,就从线程池中取出一个空闲的线程来完成成这个任务,完成后不关闭该线程,而是将该线程还回到线程池中。它主要作用是为了控制线程数量,重用线程
  
  java为我们提供了ExecutorService接口来实现线程。



我们通过api可以知道ExecutorService接口的已知实现类有3种,要想理解好线程池的工作原理我们得理解ThreadPoolExecutor。

java为ThreadPoolExecutor类提供的构造方法:

ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue)
          用给定的初始参数和默认的线程工厂及被拒绝的执行处理程序创建新的 ThreadPoolExecutor
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler)
          用给定的初始参数和默认的线程工厂创建新的 ThreadPoolExecutor
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory)
          用给定的初始参数和默认被拒绝的执行处理程序创建新的 ThreadPoolExecutor
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
          用给定的初始参数创建新的 ThreadPoolExecutor


从中我们可以看出每个构造方法都有

1. corePoolSize 

 核心线程数:池中所保存的线程数,包括空闲线程。也就是说没有任何任务过来,线程池里面也会有最基本线程数。

 2. maximumPoolSize

 最大线程数:池中允许的最大线程数。

 3. keepAliveTime

 空闲线程最大存活时间:当线程数大于核心时,此为终止前多余的空闲线程等待新任务的最长时间。

 4. blockingQueue

 任务队列:执行前用于保持任务的队列。此队列仅保持由 execute 方法提交的 Runnable 任务。用来存放待处理的任务。


 我们来看一个经典的例子,生产者与消费者。

   生产者:不断产生新的需要解决的任务。

   消费者:不断解决产生的问题。

   将两者联系起来就是BlockingQueue(双缓冲队列了)。它可以同时向队列一个做存储,一个做取出操作。简单的理解就是将接收的任务放入任务队列中。

   ·生产者将不断产生的任务放入到队列中,如果队列满了,生产者等待。

   ·消费者不断的从队列中取出任务解决,当队列空了,消费者等待新任务到来。

  因此BlockQueue的长度我们要限制,不然如果解决者的解决能力跟不上生产者的,这个任务队列中的任务就会越来越多。此外,我们还需要限定问题解决者的(同时运行的线程)个数如果线程数太多的话会严重影响系统的稳定性。


有了对上面的理解,我们再通过图来理解线程池的原理是什么,它是如何工作的:

                                                      线程池的工作过程

                                    

                            

我们可以知道任务是提交给整个线程池,而不是直接交给某个线程,线程池在拿到任务后,它就在内部找有无空闲的线程,再把任务交给内部某个空闲的线程,一个线程同时只能执行一个任务,但可以同时向一个线程池提交多个任务。那么我们来看看一个任务是如何执行的。


                                               一个任务在线程池中执行的原理分析

                                                      

0 0
原创粉丝点击