Java线程池

栏目: Java · 发布时间: 7年前

内容简介:Java线程池(以线程池参数最多的构造函数(线程池的存在,默认会阻止主程序的自动退出。销毁掉线程池中的全部线程后,主程序才可以顺利退出。

Java线程池( java.util.concurrent.ThreadPoolExecutor )实现了接口 java.util.concurrent.ExecutorService ,将线程资源缓存起来,实现了线程的复用。

示例代码

package bj;

import io.vavr.control.Try;

import java.time.LocalTime;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
import java.util.stream.IntStream;

/**
 * Created by BaiJiFeiLong@gmail.com at 2018/12/7 上午10:05
 */
public class FooTest {

    public static void main(String[] args) {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(4, 6, 5, TimeUnit.SECONDS, new LinkedBlockingQueue<>(3), new ThreadFactory() {
            private int count = 0;

            @Override
            public Thread newThread(Runnable r) {
                return new Thread(r, String.format("Thread[%d]", ++count));
            }
        }, (r, executor1) -> System.out.println("Ignored: " + r));
        executor.allowCoreThreadTimeOut(true);
        IntStream.range(0, 10).forEach($ -> executor.execute(() -> {
            Try.run(() -> Thread.sleep(1000)).getOrElseThrow((Supplier<RuntimeException>) RuntimeException::new);
            System.out.println(String.format("%s Progress: %d Thread: %s", LocalTime.now(), $, Thread.currentThread().getName()));
        }));
    }
}

示例输出

Ignored: bj.FooTest$$Lambda$3/783286238@27082746
14:13:53.247 Progress: 0 Thread: Thread[1]
14:13:53.247 Progress: 2 Thread: Thread[3]
14:13:53.247 Progress: 8 Thread: Thread[6]
14:13:53.247 Progress: 3 Thread: Thread[4]
14:13:53.248 Progress: 1 Thread: Thread[2]
14:13:53.248 Progress: 7 Thread: Thread[5]
14:13:54.252 Progress: 5 Thread: Thread[6]
14:13:54.252 Progress: 6 Thread: Thread[3]
14:13:54.252 Progress: 4 Thread: Thread[1]

Process finished with exit code 0

线程池各参数讲解

以线程池参数最多的构造函数( java.util.concurrent.ThreadPoolExecutor#ThreadPoolExecutor(int, int, long, java.util.concurrent.TimeUnit, java.util.concurrent.BlockingQueue<java.lang.Runnable>, java.util.concurrent.ThreadFactory, java.util.concurrent.RejectedExecutionHandler) )为例

  • corePoolSize 核心池大小。核心池直接开辟空间
  • maximumPoolSize 最大池(核心池+普通池)大小 线程数量超过这个大小,会拒绝执行
  • keepAliveTime 线程存活时间 线程过了存活时间会自动销毁,默认情况下核心池例外
  • unit 线程存活时间单位
  • workQueue 工作队列 任务会在workQueue排队
  • threadFactory 线程工厂 如何创建线程。可以指定线程名称、记录日志等
  • handler 拒绝执行策略 默认抛异常,不执行

线程池基本工作流程

  1. 创建线程池,核心池分配满线程
  2. 新任务进入,放入核心池,开始执行
  3. 新任务进入,核心池已满,放入执行队列
  4. 新任务进入,执行队列已满,新任务放入普通池立即执行
  5. 新任务进入,线程数量超过最大池大小,拒绝执行
  6. 任务执行完毕,进入等待状态。普通池的线程超时后自动销毁
  7. 如果 allowCoreThreadTimeOut 设为 true ,核心池中的线程超时后自动销毁

示例程序中,各任务的流向

  1. 任务1,放入核心池执行
  2. 任务2,放入核心池执行
  3. 任务3,放入核心池执行
  4. 任务4,放入核心池执行
  5. 任务5,核心池已满,放入执行队列等待
  6. 任务6,核心池已满,放入执行队列等待
  7. 任务7,核心池已满,放入执行队列等待
  8. 任务8,核心池和指定队列都已满,放入普通池立即执行
  9. 任务9,核心池和指定队列都已满,放入普通池立即执行
  10. 任务10, 核心池+普通池已达上限,任务被拒绝执行

线程池任务执行完成后自动销毁全部线程

线程池的存在,默认会阻止主程序的自动退出。销毁掉线程池中的全部线程后,主程序才可以顺利退出。

实现线程池任务全部接触后,自动销毁全部线程,有两种方式:

executor.allowCoreThreadTimeOut(true);
executor.setCorePoolSize(0);

文章首发: https://baijifeilong.github.io


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。

一站式学习C编程

一站式学习C编程

宋劲杉 / 电子工业出版社 / 2011-3 / 59.00元

《一站式学习c编程》有两条线索,一条线索是以linux平台为载体全面深入地介绍c语言的语法和程序的工作原理,另一条线索是介绍程序设计的基本思想和开发调试方法。本书分为两部分:第一部分讲解编程语言和程序设计的基本思想方法,让读者从概念上认识c语言;第二部分结合操作系统和体系结构的知识讲解程序的工作原理,让读者从本质上认识c语言。 《一站式学习c编程》适合做零基础的初学者学习c语言的第一本教材,......一起来看看 《一站式学习C编程》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

SHA 加密
SHA 加密

SHA 加密工具