线程池的使用
2021-03-05 05:29
标签:term exe 大于 并发 rest 不执行 抛出异常 current cached 减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务。 可以根据系统的承受能力,调整线程池中工作线线程的数目,防止消耗过多的内存。 java.uitl.concurrent.ThreadPoolExecutor类是线程池中最核心的一个类。 在ThreadPoolExecutor类中提供了四个构造方法: 从上面的代码可以得知,ThreadPoolExecutor继承了AbstractExecutorService类,并提供了四个构造器,事实上,通过观察每个构造器的源码具体实现,发现前面三个构造器都是调用的第四个构造器进行的初始化工作。 下面解释下一下构造器中各个参数的含义: ThreadPoolExecutor池子的处理流程如下: 1)当池子大小小于corePoolSize就新建线程,并处理请求 2)当池子大小等于corePoolSize,把请求放入workQueue中,池子里的空闲线程就去从workQueue中取任务并处理 3)当workQueue放不下新入的任务时,新建线程入池,并处理请求,如果池子大小撑到了maximumPoolSize就用RejectedExecutionHandler来做拒绝处理 4)另外,当池子的线程数大于corePoolSize的时候,多余的线程会等待keepAliveTime长的时间,如果无请求可处理就自行销毁。 创建线程时会优先创建 CorePoolSiz 线程, 当继续增加线程时,先放入Queue中,当 CorePoolSiz 和 Queue 都满的时候,就增加创建新线程,当线程达到MaxPoolSize的时候,就会抛出错误 org.springframework.core.task.TaskRejectedException。 在ThreadPoolExecutor类中有几个非常重要的方法: execute()、submit()、shutdown()、shutdownNow() 在ThreadPoolExecutor中定义了一个volatile变量,另外定义了几个static final变量表示线程池的各个状态: runState表示当前线程池的状态,它是一个volatile变量用来保证线程之间的可见性; 下面的几个static final变量表示runState可能的几个取值。 默认情况下,创建线程池之后,线程池中是没有线程的,需要提交任务之后才会创建线程。 在实际中如果需要线程池创建之后立即创建线程,可以通过以下两个方法办到: 在前面我们多次提到了任务缓存队列,即workQueue,它用来存放等待执行的任务。 workQueue的类型为BlockingQueue 当线程池的任务缓存队列已满并且线程池中的线程数目达到maximumPoolSize,如果还有任务到来就会采取任务拒绝策略,通常有以下四种策略: ThreadPoolExecutor提供了两个方法,用于线程池的关闭,分别是shutdown()和shutdownNow(),其中: ThreadPoolExecutor提供了动态调整线程池容量大小的方法:setCorePoolSize()和setMaximumPoolSize(), Java通过Executors提供四种线程池,分别为: 线程数是5,执行10个任务,执行完毕之后关闭线程池 线程池的使用 标签:term exe 大于 并发 rest 不执行 抛出异常 current cached 原文地址:https://www.cnblogs.com/ljk-shm-0208/p/14332372.html1、为什么使用线程池
2、Java中的ThreadPoolExecutor类
public class ThreadPoolExecutor extends AbstractExecutorService {
.....
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
BlockingQueue
TimeUnit.DAYS; //天
TimeUnit.HOURS; //小时
TimeUnit.MINUTES; //分钟
TimeUnit.SECONDS; //秒
TimeUnit.MILLISECONDS; //毫秒
TimeUnit.MICROSECONDS; //微妙
TimeUnit.NANOSECONDS; //纳秒
ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务
3、深入剖析线程池实现原理
3.1 线程池状态
volatile int runState;
static final int RUNNING = 0;
static final int SHUTDOWN = 1;
static final int STOP = 2;
static final int TERMINATED = 3;
3.2 线程池中的线程初始化
prestartCoreThread():初始化一个核心线程;
prestartAllCoreThreads():初始化所有核心线程
3.3 任务缓存队列及排队策略
3.4 任务拒绝策略
ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务
3.5 线程池的关闭
shutdown():不会立即终止线程池,而是要等所有任务缓存队列中的任务都执行完后才终止,但再也不会接受新的任务
shutdownNow():立即终止线程池,并尝试打断正在执行的任务,并且清空任务缓存队列,返回尚未执行的任务
3.6 线程池容量的动态调整
setCorePoolSize:设置核心池大小
setMaximumPoolSize:设置线程池最大能创建的线程数目大小
4、四种线程池
5、例子
//使用isTerminated判断线程是否执行完成
public class Test2 {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(5);
for(int i=0;i){
executorService.execute(new Runnable() {
@Override
public void run() {
try {
System.out.println("线程名称"+Thread.currentThread().getName());
Thread.sleep(1000*3);
System.out.println("线程名称"+Thread.currentThread().getName()+"结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
System.out.println("开始关闭线程池,不再接受新任务");
executorService.shutdown();
System.out.println("===========");
//等待所有线程执行完成
while (!executorService.isTerminated()) {
}
System.out.println("线程池关闭完成");
}
}
}
//使用CountDownLatch判断线程是否执行完成
public class Test {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(5);
final CountDownLatch countDownLatch = new CountDownLatch(10);
for(int i=0;i){
executorService.execute(new Runnable() {
@Override
public void run() {
try {
System.out.println("线程名称"+Thread.currentThread().getName());
Thread.sleep(1000*3);
System.out.println("线程名称"+Thread.currentThread().getName()+"结束");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
//计数器减一
countDownLatch.countDown();
}
}
});
}
try {
//等待所有线程执行结束
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("开始关闭线程池");
executorService.shutdown();
System.out.println("线程池关闭完成");
}
}
}
//使用Future 得到线程任务返回结果
public class Test {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(5);
List
}
下一篇:Java多线程