本文对Executor、以及ThreadPoolExecutor中,可能用到的方法、参数做出介绍,文章参考了大量的博客以及API,最后总结得出,希望可以作为一本小字典,供大家翻阅。
文章内容过多,无法一一用简洁明了的话跟大家解释,如果有一些谬误,欢迎指出,我会及时纠正,有其他意见或者建议,也欢迎留言。结尾附上我的测试Demo,我会对各个线程池的作用进行测试。
关于Executors的介绍,建议看完ThreadPoolExecutor再回来看吧,但是使用起来确实简单,Executors提供了四种定义好的线程池,分别为:
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行,他有几个特殊的方法(也是执行runnable的方法,具有延迟执行的特点):
Executors提供的线程服务,通过参数设置来实现不同的线程池机制。
此包中所定义的Executor、ExecutorService、ScheduledExecutorService、ThreadFactory
和Callable 类的工厂和实用方法。此类支持以下各种方法:
一句话概括:小于max就能新建线程,大于corePoolSize就放入WorkQueue缓冲队列,超过最大处理能力就交给Handler处理,超过最大存活时间线程池就会关闭(超出corePoolSize部分,也可自定义),线程池分类不同,具体情况略有不同:
1.当线程池小于corePoolSize时,新提交任务将创建一个新线程执行任务,即使此时线程池中存在空闲线程。
2.当线程池达到corePoolSize时,新提交任务将被放入workQueue中,等待线程池中任务调度执行
3.当workQueue已满,且maximumPoolSize>corePoolSize时,新提交任务会创建新线程执行任务
4.当提交任务数超过maximumPoolSize时,新提交任务由RejectedExecutionHandler处理
5.当线程池中超过corePoolSize线程,空闲时间达到keepAliveTime时,关闭空闲线程
6.当设置allowCoreThreadTimeOut(true)时,线程池中小于corePoolSize的线程空闲时间达到keepAliveTime也将关闭
多少时间自动回收线程?参数为java.util.concurrent.TimeUnit中的几个静态属性:
一次写了太多事务,线程池处理不过来,先装起来。 workQueue指的是阻塞队列,用来存储等待执行的任务,这个参数的选择也很重要,会对线程池的运行过程产生重大影响,一般来说,这里的阻塞队列有以下几种选择:
其中LinkedBlockingQueue和ArrayBlockingQueue比较起来,它们背后所用的数据结构不一样,导致LinkedBlockingQueue的数据吞吐量要大于ArrayBlockingQueue,但在线程数量很大时其性能的可预见性低于ArrayBlockingQueue.
handler:事务太多,是拒绝?还是接受?表示当拒绝处理任务时的策略,有以下四种取值:
线程执行
线程关闭
其它
ThreadPoolExecutor类中其他的一些比较重要成员变量
class MyRunnable implements Runnable{
private boolean stop;
private Thread thread;
public MyRunnable() {
stop = false;
thread = Thread.currentThread();
}
@Override
public void run() {
int count = 0;
while (!stop) {
try {
System.out.println(count++);
Thread.sleep(200);
} catch (InterruptedException e) {
this.thread.interrupt();
}
}
}
public void stopThread() {
this.stop = !stop;
}
}
public class SafelyStop {
public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable();
Thread thread = new Thread(myRunnable);
thread.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
myRunnable.stopThread();
}
}
package com;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class Test {
/** * 容量大小固定的线程池:因为线程池大小限制为4,所以一次输出4个数字,并且会发现线程被复用了 */
public static void testFixedThreadPool() {
for (int i = 0; i < 10; i++) {
final int index = i;
ThreadUtil.getFixedThreadPool().execute(new Runnable() {
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + ":" + index);
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
/** * 带延迟效果的线程池:线程延迟了3秒执行,容量大小,而且线程只新建了3个 */
public static void testScheduledThreadPool1() {
for (int i = 0; i < 10; i++) {
ThreadUtil.getScheduledThreadPool().schedule(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + ":" + "delay 3 seconds");
}
}, 3, TimeUnit.SECONDS);
}
}
/** * 带延迟效果的线程池:线程延迟了1秒执行,之后每3秒执行一次,而且线程是3个中的随机一个,以固定的周期执行 */
public static void testScheduledThreadPool2() {
ThreadUtil.getScheduledThreadPool().scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + ":" + "delay 3 seconds");
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, 1, 2, TimeUnit.SECONDS);
}
/** * 带延迟效果的线程池:线程延迟了1秒执行,之后每3秒执行一次,而且线程是3个中的随机一个,执行完任务,以固定的周期进行延迟 */
public static void testScheduledThreadPool3() {
ThreadUtil.getScheduledThreadPool().scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + ":" + "delay 3 seconds");
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, 1, 2, TimeUnit.SECONDS);
}
/** * 可自动回收线程的线程池:Java默认60秒自动回收,测试回收功能 */
public static void testCachedThreadPool() {
for (int i = 0; i < 10; i++) {
final int index = i;
ThreadUtil.getCachedThreadPool().execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + ":" + index);
}
});
try {
Thread.sleep(70000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/** * 这是一个单例线程,可以看到:所有的事务使用同一个线程 */
public static void testSingleThreadExecutor() {
for (int i = 0; i < 10; i++) {
final int index = i;
ThreadUtil.getSingleThreadExecutor().execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + ":" + index);
}
});
}
}
/** * 自定义线程池测试 */
public static void testThreadPoolExecutor() {
for (int i = 1; i < 20; i++) {
System.out.println("提交第" + i + "个任务!");
ThreadUtil.getThreadpool().execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "running=====");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "finish=====");
}
});
}
}
public static void main(String[] args) throws Exception {
// testFixedThreadPool();
// testCachedThreadPool();
// testScheduledThreadPool2();
testSingleThreadExecutor();
}
}
包含了以上提到的全部线程
class ThreadUtil {
private static ThreadPoolExecutor threadPool;
private static ExecutorService cachedThreadPool;
private static ExecutorService fixedThreadPool;
private static ScheduledExecutorService scheduledThreadPool;
private static ExecutorService singleThreadExecutor;
/** * 个人比较喜欢的一种单例模式写法,不知道有没有人这么写 * * @return 线程池 */
public static ThreadPoolExecutor getThreadpool() {
if (threadPool == null)
createThreadPool();
return threadPool;
}
public static ExecutorService getCachedThreadPool() {
if (cachedThreadPool == null)
crateCachedThreadPool();
return cachedThreadPool;
}
public static ExecutorService getFixedThreadPool() {
if (fixedThreadPool == null)
crateFixedThreadPool();
return fixedThreadPool;
}
public static ScheduledExecutorService getScheduledThreadPool() {
if (scheduledThreadPool == null)
crateScheduledThreadPool();
return scheduledThreadPool;
}
public static ExecutorService getSingleThreadExecutor() {
if (singleThreadExecutor == null)
crateSingleThreadExecutor();
return singleThreadExecutor;
}
/** * 单例线程 */
private static void crateSingleThreadExecutor() {
if (singleThreadExecutor == null)
singleThreadExecutor = Executors.newSingleThreadExecutor(new CustomThreadFactory());
}
/** * 创建一个定长线程池,支持定时及周期性任务执行。 */
private static void crateScheduledThreadPool() {
if (scheduledThreadPool == null)
scheduledThreadPool = Executors.newScheduledThreadPool(3, new CustomThreadFactory());
}
/** * 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。 */
private static void crateFixedThreadPool() {
if (fixedThreadPool == null)
fixedThreadPool = Executors.newFixedThreadPool(4, new CustomThreadFactory());
}
/** * 带缓存的队列,如果有新的事务,自动使用之前的线程,线程会自动回收 */
private static void crateCachedThreadPool() {
if (cachedThreadPool == null)
cachedThreadPool = Executors.newCachedThreadPool(new CustomThreadFactory());
}
/** * 自定义线程池 */
private synchronized static void createThreadPool() {
if (threadPool == null)
threadPool = new ThreadPoolExecutor(
3, // 线程数量
5, // 线程池最大值
2, // 最大存活时间
TimeUnit.SECONDS, // 按照秒计算
new ArrayBlockingQueue<Runnable>(5), // 缓冲池(阻塞队列)
new CustomThreadFactory(), // 线程工厂
new CustomRejectedExecutionHandler()// 超出最大处理能力处理机制(拒绝策略)
);
}
/** * 关闭所有的线程 */
public static void destory() {
if (!threadPool.isShutdown()) {
threadPool.shutdownNow();
}
}
/** * 自定义线程工厂,这里给每一个线程取了一个名字 * * @author ChenSS * */
private static class CustomThreadFactory implements ThreadFactory {
private AtomicInteger count = new AtomicInteger(0);
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r);
String threadName = ThreadFactory.class.getSimpleName() + count.addAndGet(1);
thread.setName(threadName);
return thread;
}
}
/** * 自定义处理策略 * * @author ChenSS * */
private static class CustomRejectedExecutionHandler implements RejectedExecutionHandler {
@Override
public void rejectedExecution(Runnable runnable, ThreadPoolExecutor executor) {
try {
// 超出最大线程池极限的时候的处理机制,这里也可以直接拒绝、或者说抛出异常,而这里是等待
executor.getQueue().put(runnable);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/** * 下面是一个添加了简单的暂停/恢复功能的子类: * * @author ChenSS * */
class PausableThreadPoolExecutor extends ThreadPoolExecutor {
private boolean isPaused;
private ReentrantLock pauseLock = new ReentrantLock();
private Condition unpaused = pauseLock.newCondition();
public PausableThreadPoolExecutor(……){
//构造方法,需要哪个自己选择super(......)
}
protected void beforeExecute(Thread t, Runnable r) {
pauseLock.lock();
try {
while (isPaused)
unpaused.await();
} catch (InterruptedException ie) {
t.interrupt();
} finally {
pauseLock.unlock();
}
super.beforeExecute(t, r);
}
public void pause() {
pauseLock.lock();
try {
isPaused = true;
} finally {
pauseLock.unlock();
}
}
public void resume() {
pauseLock.lock();
try {
isPaused = false;
unpaused.signalAll();
} finally {
pauseLock.unlock();
}
}
/** * 当不再引用此执行程序时,调用 shutdown。 */
@Override
protected void finalize() {
//关闭前做什么?功能自己扩展……
super.finalize();
}
}