JAVA 线程池 (一)

2014-11-24 10:26:34 · 作者: · 浏览: 0

、ThreadPoolExecutor的使用

1.ThreadPoolExecutor的完整构造方法是:


ThreadPoolExecutor ( int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue< Runnable > workQueue, RejectedExecutionHandler hander)


2.Executors中的几个工厂方法

ThreadPoolExecutor是Executors类的底层实现

①newFixedThreadPool ( int nThreads)——固定大小线程池


[java]
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue());
}

public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue());
}
可以看到corePoolSize和maximunPoolSize的大小是一样的(其实使用无界Queue的话maximumPoolSize参数是没有意义的),keepAliveTime和unit的设置表明该实现不想keepAlive,最后的BlockingQueue选择了LinkedBlockingQueue,该Queue有一个特点就是它是无界的;

②newSingleThreadExecutor()——单线程


[java]
public static ExecutorService newSingleThreadExecutor() {
return new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue());
}

public static ExecutorService newSingleThreadExecutor() {
return new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue());
}
③newCachedThreadPool()——无界线程池,可以进行自动线程回收


[java]
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue());
}

public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue());
}

在BlockingQueue的选择上使用SynchronousQueue,在该Queue中,每个插入操作必须等待另一个线程的对应移除操作。比如,我先添加一个元素,接下来如果想继续添加则会阻塞,直到另一个线程取走一个元素,反之亦然(也就是缓冲区为1的生产者消费者模式)。

3.corePoolSize、workQueue、maximumPoolSize的优先级

当一个任务通过execute(Runnable)方法欲添加到线程池时:
如果此时线程池中的数量小于corePoolSize,即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务。

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

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

如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量等于maximumPoolSize,那么通过 handler所指定的策略来处理此任务。


也就是:处理任务的优先级为:

核心线程corePoolSize、任务队列workQueue、最大线程maximumPoolSize,如果三者都满了,使用handler处理被拒绝的任务。

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


二、BlockingQueue workQueue

1.BlockingQueue的作用

所有的BlockingQueue都可以用于传输和保持提交的任务,可以使用此队列对池大小进行交互。

如果运行的线程小于corePoolSize,则Executor始终首选添加新的线程,而不进行排队,也就是当当前运行的线程小于corePoolSize时,则任务根本不会存放,添加到Queue中,而是直接创建一个新的thread;

如果运行的线程等于或多余corePoolSize,则Executor首选将请求加入Queue,而不是添加新的thread;

如果无法将请求加入Queue,则创建新线程,除非创建此线程超出maximumPoolSize,在这种情况下,任务将被拒绝。

2.排队的三种策略

①直接提交,工作队列的默认选项是Synchro