根据阿里巴巴的JAVA开发手册推荐用ThreadPoolExecutor创建线程池(Executors 这个Java中的工具类创建的线程池,可能会耗费非常大的内存,甚至 OOM)
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.*;
@Slf4j
public class ThreadUtils {
public static Integer someThreado(String str){
long strat = System.currentTimeMillis();
FutureTask<Integer> aFutureTask = new FutureTask<>(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return add("a",str);
}
});
FutureTask<Integer> bFutureTask = new FutureTask<>(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return add("b",str);
}
});
FutureTask<Integer> cFutureTask = new FutureTask<>(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return add("c",str);
}
});
/**
* corePoolSize 线程池核心池的大小
* maximumPoolSize 线程池中允许的最大线程数量
* keepAliveTime 当线程数大于核心时,此为终止前多余的空闲线程等待新任务的最长时间
* unit keepAliveTime 的时间单位
* workQueue 用来储存等待执行任务的队列
* threadFactory 创建线程的工厂类
* handler 拒绝策略类,当线程池数量达到上线并且workQueue队列长度达到上限时就需要对到来的任务做拒绝处理
* 原理:
* 有请求时,创建线程执行任务,当线程数量等于corePoolSize时,请求加入阻塞队列里,当队列满了时,接着创建线程,
* 线程数等于maximumPoolSize。 当任务处理不过来的时候,线程池开始执行拒绝策略。
* 换言之,线程池最多同时并行执行maximumPoolSize的线程,最多处理maximumPoolSize+workQueue.size()的任务。多余的默认采用AbortPolicy会丢弃。
* 阻塞队列:
* ArrayBlockingQueue :一个由数组结构组成的有界阻塞队列。
* LinkedBlockingQueue :一个由链表结构组成的有界阻塞队列。
* PriorityBlockingQueue :一个支持优先级排序的无界阻塞队列。
* DelayQueue: 一个使用优先级队列实现的无界阻塞队列。
* SynchronousQueue: 一个不存储元素的阻塞队列。
* LinkedTransferQueue: 一个由链表结构组成的无界阻塞队列。
* LinkedBlockingDeque: 一个由链表结构组成的双向阻塞队列。
* 拒绝策略:
* ThreadPoolExecutor.AbortPolicy: 丢弃任务并抛出RejectedExecutionException异常。 (默认)
* ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
* ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务。(重复此过程)
* ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务。
*/
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3, 30, 5, TimeUnit.SECONDS, new LinkedBlockingDeque<>(300));
threadPoolExecutor.submit(aFutureTask);
threadPoolExecutor.submit(bFutureTask);
threadPoolExecutor.submit(cFutureTask);
log.info("当前活动线程数:{},线程池线程数量:{}",threadPoolExecutor.getActiveCount(),threadPoolExecutor.getPoolSize());
Integer res = 0;
try {
Integer a = aFutureTask.get();
Integer b = bFutureTask.get();
Integer c = cFutureTask.get();
res = a + b + c;
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}finally {
threadPoolExecutor.shutdown();//关闭线程池
}
long times = System.currentTimeMillis() - strat;
log.info("所花时间:{}",times);
return res;
}
public static Integer add(String flag,String str){
System.out.println(str);
int res = 0;
if("a".equals(flag)){
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return 1;
}
else if("b".equals(flag)){
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return 2;
}else {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return res;
}
public static void main(String[] args) {
Integer test = ThreadUtils.someThreado("Test");
System.out.println("结果======"+test);
}
}