线程池,当一个任务进入线程池后,线程池是如何执行的? 线程池的执行流程是: 先判断当前线程数是否大于核心线程数?如果结果为 false,则新建线程并执行任务;如果结果为 true,则判断是否大于任务队列?如果结果为 false,则把任务添加到任务队列中等待线程执行,否则判断当前线程数量是否大于最大线程数?如果结果为 false,则新建线程执行此任务,否则将执行线程池的拒绝策略。 实例
private static void test1() {
// 任务的具体方法
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("当前任务被执行,执行时间:" + new Date() + " 执行线程:" + Thread.currentThread().getName());
try {
// 等待 1s
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
// 创建线程,线程的任务队列的长度为 1
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
1,
1,
100,
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(1),
new ThreadPoolExecutor.DiscardPolicy());
// 添加并执行 4 个任务
threadPool.execute(runnable);
threadPool.execute(runnable);
threadPool.execute(runnable);
threadPool.execute(runnable);
// 线程池执行完任务,关闭线程池
threadPool.shutdown();
}
其中DiscardPolicy:忽略此任务,忽略最新的一个任务;从结果可以看出给线程池添加了4个任务,线程池根据执行流程只执行了2个任务就结束了,有2个任务被忽略了。
private static void test2() {
// 任务的具体方法
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("当前任务被执行,执行时间:" + new Date() + " 执行线程:" + Thread.currentThread().getName());
try {
// 等待 1s
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
// 创建线程,线程的任务队列的长度为 1
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
1,
1,
100,
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(1),
new ThreadPoolExecutor.AbortPolicy());
// 添加并执行 4 个任务
threadPool.execute(runnable);
threadPool.execute(runnable);
threadPool.execute(runnable);
threadPool.execute(runnable);
// 线程池执行完任务,关闭线程池
threadPool.shutdown();
}
其中AbortPolicy:中止策略,线程池会抛出异常并中止执行此任务;从结果可以看出给线程池添加了4个任务,线程池根据执行流程只执行了2个任务,有2个任务执行了中止策略,抛出了异常。
|