线程池

Java线程池相关讲解

概述

​ 线程池是一种多线程处理形式, 处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务

创建
构造函数:
public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        ...
        ...
        ...
    }
参数详情
  1. corePoolSize:核心线程数量,当线程数达corePoolSize时会把到达的任务放到缓存队列

  2. maximumPoolSize:线程池中最大能创建的线程的数量

  3. keepAliveTime:保证线程存活时间,若线程数超过了corePoolSize,某线程闲置时间超过keepAliveTime时,该线程会被销毁

  4. TimeUnit:keepAliveTime时长对应的单位

    ​ NANO_SCALE:千分之一微秒

    ​ MICRO_SCALE:微秒

    ​ MILLI_SCALE:毫秒

    ​ SECOND_SCALE:秒

    ​ MINUTE_SCALE:分钟

    ​ HOUR_SCALE:小时

  5. BlockingQueue:阻塞队列,存储等待执行的任务

  6. ThreadFactory:创建线程的工厂

  7. RejectedExecutionHandler:处理线程池及队列满载后的拒绝请求处理器

线程池工作流程
首先创建一个线程池对象,调用execute()方法添加任务并执行,
如果池中运行的线程数小于corePoolSize,直接启动一个线程去执行当前任务
如果池中运行的线程数大于等于corePoolSize,当前任务会进入等待队列,
如果等待队列满了,总的线程数小于maximumPoolSize,则会创建非核心线程去执行当前任务
如果队列满了,正在运行的线程数大于等于maximumPoolSize,则会抛出异常RejectExecutionException

当一个线程执行完任务后,会从等待队列去一个任务执行,如果一个线程空闲的时间超过keepAliveTime,并且当前运行的内存数超过corePoolSize,该线程就会被停止。
线程池的扩展用法

1.缓存线程池

/**
* 缓存线程池.
* (长度无限制)
* 执行流程:
* 1. 判断线程池是否存在空闲线程
* 2. 存在则使用
* 3. 不存在,则创建线程 并放入线程池, 然后使用
*/
ExecutorService service = Executors.newCachedThreadPool();
        //指挥线程池执行新的任务
        service.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"锄禾日当午");
            }
        });

2.定长线程池

/**
* 定长线程池.
* (长度是指定的数值)
* 执行流程:
* 1. 判断线程池是否存在空闲线程
* 2. 存在则使用
* 3. 不存在空闲线程,且线程池未满的情况下,则创建线程 并放入线程池, 然后使用
* 4. 不存在空闲线程,且线程池已满的情况下,则等待线程池存在空闲线程
*/
ExecutorService service = Executors.newFixedThreadPool(2);
        service.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"锄禾日当午");
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

3.单线程线程池

效果与定长线程池 创建时传入数值1 效果一致.
/**
* 单线程线程池.
* 执行流程:
* 1. 判断线程池 的那个线程 是否空闲
* 2. 空闲则使用
* 4. 不空闲,则等待 池中的单个线程空闲后 使用
*/
ExecutorService service = Executors.newSingleThreadExecutor();
        service.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"锄禾日当午");
            }
        });

4.周期性任务定长线程池

/**
* 周期任务 定长线程池.
* 执行流程:
* 1. 判断线程池是否存在空闲线程
* 2. 存在则使用
* 3. 不存在空闲线程,且线程池未满的情况下,则创建线程 并放入线程池, 然后使用
* 4. 不存在空闲线程,且线程池已满的情况下,则等待线程池存在空闲线程
*
* 周期性任务执行时:
* 定时执行, 当某个时机触发时, 自动执行某任务 .
*/


/**
         * 1.   定时执行一次
         * 参数1. 定时执行的任务
         * 参数2. 时长数字
         * 参数3. 时长数字的时间单位 , TimeUnit的常量指定
         */
        service.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("锄禾日当午");
            }
        },5, TimeUnit.SECONDS);
        
/**
         * 2.	周期性执行任务
         * 参数1. 任务
         * 参数2. 延迟时长数字(第一次执行在什么时间以后)
         * 参数3. 周期时长数字(每隔多久执行一次)
         * 参数4. 时长数字单位
         */
        service.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                System.out.println("汗滴禾下土");
            }
        },5,1,TimeUnit.SECONDS);      
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值