首先先看一下ThreadPoolExecutor线程池的构造方法
ThreadPoolExecutor
(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, ThreadFactory threadFactory,RejectedExecutionHandler handler)
这里主要需要了解四个关键字
int corePoolSize
线程池的基础大小(核心线程数),默认情况下核心线程会一直存活,即使处于闲置状态也不会受存keepAliveTime
限制
当提交一个任务到线程池时,线程池会创建一个线程来执行任务,即使其他空闲的基本线程能够执行新任务也会创建线程,等到需要执行的任务数大于线程池基本大小时就不再创建。如果调用了线程池的prestartAllCoreThreads
方法,线程池会提前创建并启动所有基本线程。
maximumPoolSize
线程池所能容纳的最大线程数。超过这个数的线程将被阻塞。不要理解为线程池所能创建的线程数,线程池会根据不同的情况(即使用哪种BlockingQuene)来确定最多创建多少线程, 而且不能理解为同一时间能创建maxmunPooSize个线程, 需要根据BlockingQuene来区别。 先不讲解, 后面详细说明,这里单单提出一种: 当任务队列(workQueue)为没有设置大小的LinkedBlockingDeque时(详看下面这一行代码),maximunPoolSize这个值无效.
threadPool = new ThreadPoolExecutor(CORE_POOL_SIZE, MAX_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.SECONDS,new LinkedBlockingDeque<>())
keepAliveTime
非核心线程的闲置超时时间,超过这个时间就会被回收
unit
指定keepAliveTime
的单位,如TimeUnit.SECONDS
。当将allowCoreThreadTimeOut
设置为true
时对corePoolSize生效
workQueue
任务队列(阻塞队列)用于保存等待执行的任务的阻塞队列, 有以下三种阻塞队列
SynchronousQueue
,LinkedBlockingDeque
,ArrayBlockingQueue
new LinkedBlockingQueue<>(30) //有界 new LinkedBlockingQueue<>() //无界
测试
通过设置以下红色部分的值来校验结果
public class TestThreadPool {
static CountDownLatch count = null;
public static void main(String[] args) {
// TODO Auto-generated method stub
List list = new ArrayList();
for(int i= 1; i <= 200; i++){
list.add("list" + i);
}
count = new CountDownLatch(list.size());
List> callableList = new ArrayList<>();
for (int i = 0; i < list.size(); i++) {
final String listName = list.get(i);
TestCallable callable = new TestCallable<>(listName);
callableList.add(callable);
}
List> futures = ThreadPoolUtil.exeCallableList(callableList);
System.err.println("下一个task。。");
ThreadPoolUtil.shutDown(true);
}
}
package com.yaya.thread.future;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;
public class ThreadPoolUtil {
// 线程池
private static ThreadPoolExecutor threadPool;
// 线程池核心线程数
private static final int CORE_POOL_SIZE = 3;
// 线程池最大线程数
private static final int MAX_POOL_SIZE = 20;
// 额外线程空状态生存时间
private static final int KEEP_ALIVE_TIME = 10000;
private static final int CANCEL_TASK_TIME = 20;
private ThreadPoolUtil() {
}
static {
threadPool = new ThreadPoolExecutor(CORE_POOL_SIZE, MAX_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(30), new ThreadFactory() {
private final AtomicInteger integer = new AtomicInteger();
@Override
public Thread newThread(Runnable r) {
return new Thread(r, "mock thread:" + integer.getAndIncrement());
}
});
}
/**
* 从线程池中抽取线程,执行指定的Runnable对象
*
* @param runnable
*/
public static void execute(Runnable runnable) {
threadPool.execute(runnable);
}
/**
* 批量执行 Runnable任务
*
* @param runnableList
*/
public static void exeRunnableList(List runnableList) {
for (Runnable runnable : runnableList) {
threadPool.execute(runnable);
}
}
/**
* 从线程池中抽取线程,执行指定的Callable对象
*
* @param callable
* @return 返回执行完毕后的预期结果
*/
public static Future exeCallable(Callable callable) {
return threadPool.submit(callable);
}
/**
* 批量执行 Callable任务
*
* @param callableList
* callable的实例列表
* @return 返回指定的预期执行结果
*/
public static List> exeCallableList(List> callableList) {
List> futures = null;
try {
futures = threadPool.invokeAll(callableList);
} catch (InterruptedException e) {
e.printStackTrace();
}
return futures;
}
/**
* 中断任务的执行
*
* @param isForceClose
* true:强制中断 false:等待任务执行完毕后,关闭线程池
*/
public static void shutDown(boolean isForceClose) {
if (isForceClose) {
threadPool.shutdownNow();
} else {
threadPool.shutdown();
}
}
/**
* 若超出CANCEL_TASK_TIME的时间,没有得到执行结果,则尝试中断线程
*
* @param future
* @return 中断成功,则返回true 否则返回false
*/
public static boolean attemptCancelTask(Future future) {
boolean cancel = false;
try {
future.get(CANCEL_TASK_TIME, TimeUnit.MINUTES);
cancel = true;
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
cancel = future.cancel(true);
e.printStackTrace();
}
return cancel;
}
}
package com.yaya.thread.future;
public class TestCallable implements Callable {
String appid;
public TestCallable(java.lang.String appid) {
this.appid = (String) appid;
}
@Override
public String call() throws Exception {
// Thread.sleep(1000);
// System.err.println("task" + this.appid + "睡了1s");
Thread.sleep(3000);
System.err.println("task" + this.appid+"睡了3s");
// System.err.println("task" + this.appid + "睡了3s");
return (String) ("task" + this.appid+ " return");
}
}