Java线程池

来源:互联网 发布:美国失业金数据公布 编辑:程序博客网 时间:2024/06/05 03:56

http://blog.csdn.net/wangpeng047/article/details/7748457

一、线程池的作用

线程池作用就是限制系统中执行线程的数量。

根据系统的环境情况,可以自动或手动设置线程数量,达到运行的最佳效果;如果线程少了会浪费系统资源,多了又会造成系统拥挤效率不高。用线程池控制线程数量,使得其他线程排队等候。一个任务执行完毕,再从队列的中取最前面的任务开始执行。若队列中没有任务等待进程,则线程池中的线程处于等待。

二、为什么要用线程池

减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务。也可以根据系统的承受能力,调整线程池中工作线线程的数目,防止因为消耗过多的内存,而把服务器累趴下(每个线程需要大约1MB内存,线程开的越多,消耗的内存也就越大,最后死机)。

三、线程池的原理

其实线程池的原理很简单,类似于操作系统中的缓冲区的概念,它的流程如下:先启动若干数量的线程,并让这些线程都处于睡眠状态,当客户端有一个新请求时,就会唤醒线程池中的某一个睡眠线程,让它来处理客户端的这个请求,当处理完这个请求后,线程又处于睡眠状态。

四、java线程池

java关于线程池的主要内容有:

接口:Executor、ExecutorService、ScheduledExecutorService、CompletionService

类:Executors、AbstractExecutorService、ThreadPoolExecutor、ScheduledThreadPoolExecutor、ExecutorCompletionService

以上这些,我不可能一一介绍,这里只介绍重要的两个类Executors和ThreadPoolExecutor


1. ThreadPoolExecutor

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler)

参数:

● corePoolSize - 池中所保存的线程数,包括空闲线程。

● maximumPoolSize - 池中允许的最大线程数。

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

● unit - keepAliveTime 参数的时间单位。

● workQueue - 执行前用于保持任务的队列。此队列仅保持由 execute 方法提交的 Runnable 任务。

● threadFactory - 执行程序创建新线程时使用的工厂。

● handler - 由于超出线程范围和队列容量而使执行被阻塞时所使用的处理程序。

抛出:

● IllegalArgumentException - 如果 corePoolSize 或 keepAliveTime 小于 0,或者 maximumPoolSize 小于等于 0,或者 corePoolSize 大于 maximumPoolSize。

● NullPointerException - 如果 workQueue、threadFactory 或 handler 为 null。

 

● unit可选的参数为java.util.concurrent.TimeUnit中的几个静态属性:

NANOSECONDS、MICROSECONDS、MILLISECONDS、SECONDS

● workQueue我常用的是:java.util.concurrent.ArrayBlockingQueue

● handler有四个选择:

1. ThreadPoolExecutor.AbortPolicy()

抛出java.util.concurrent.RejectedExecutionException异常

2. ThreadPoolExecutor.CallerRunsPolicy()

重试添加当前的任务,他会自动重复调用execute()方法

3. ThreadPoolExecutor.DiscardOldestPolicy()

抛弃旧的任务

4. ThreadPoolExecutor.DiscardPolicy()

抛弃当前的任务

 

一个任务通过execute(Runnable)方法被添加到线程池,任务就是一个 Runnable类型的对象,任务的执行方法就是 Runnable类型对象的run()方法。

当一个任务通过execute(Runnable)方法欲添加到线程池时,会有以下:

1. 如果此时线程池中的数量小于corePoolSize,即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务。

2. 如果此时线程池中的数量等于 corePoolSize,但是缓冲队列 workQueue未满,那么任务被放入缓冲队列。

3. 如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量小于maximumPoolSize,建新的线程来处理被添加的任务。

4. 如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量等于maximumPoolSize,那么通过 handler所指定的策略来处理此任务。也就是处理任务的优先级为:核心线程corePoolSize、任务队列workQueue、最大线程maximumPoolSize,如果三者都满了,使用handler处理被拒绝的任务。

5. 当线程池中的线程数量大于 corePoolSize时,如果某线程空闲时间超过keepAliveTime,线程将被终止。这样,线程池可以动态的调整池中的线程数。




0 0
原创粉丝点击