Java线程池的相关知识

9 篇文章 0 订阅

1为什么使用线程池

没有线程池之前使用线程,需要创建线程,然后给线程分配任务,但是问题在于这时候的一个线程只能分配执行一个任务,那样如果执行多个任务,那么就需要创建多个线程,线程不能复用,用起来耗时耗资源

2线程池如何执行任务

public static void main(String[] args) {
        //创建线程任务
        Runnable task1 = new Task();
        Runnable task2 = new Task();
        Runnable task3 = new Task();
        //创建只有一个线程的线程池
        ExecutorService pool = Executors.newSingleThreadExecutor();
        //提交任务
        pool.execute(task1);
        pool.execute(task2);
        pool.execute(task3);
        //关闭线程池
        pool.shutdown();
    }

使用线程池的好处
1降低资源消耗:通已重复利用已创建的线程降低线程创建和销毁造成的消耗
2提高响应速度:当有任务时,任务不需要等到线程创建就能立即执行.
3提高了线程的可管理性:线程可以统一的分配,调优和监控.

3使用原生的方式创建线程池

四种构造方法

ThreadPoolExecutor(int corePoolSize,
                        int maximumPoolSize,
                        long keepAliveTime,
                        TimeUnit unit,
                        BlockingQueue<Runnable> workQueue) 
ThreadPoolExecutor(int corePoolSize,
                        int maximumPoolSize,
                        long keepAliveTime,
                        TimeUnit unit,
                        BlockingQueue<Runnable> workQueue,
                        ThreadFactory threadFactory)
ThreadPoolExecutor(int corePoolSize,
                        int maximumPoolSize,
                        long keepAliveTime,
                        TimeUnit unit,
                        BlockingQueue<Runnable> workQueue,
                        RejectedExecutionHandler handler)
ThreadPoolExecutor(int corePoolSize,
                        int maximumPoolSize,
                        long keepAliveTime,
                        TimeUnit unit,
                        BlockingQueue<Runnable> workQueue,
                        ThreadFactory threadFactory,
                        RejectedExecutionHandler handler)

参数含义

  1. corePoolSize 核心线程数
  2. maximumPoolSize 最大线程数
  3. keepAliveTime 空闲线程存活时间
  4. unit 时间单位
  5. workQueue 任务队列
  6. threadFactory 线程工厂
  7. handler 任务拒绝策略

核心线程是只要线程池不关闭,他就不会被消耗
最大线程数是线程池允许创建的最大线程数
空闲线程存活时间:非核心线程,没有执行任务空闲时的存活时间
时间单位:空闲线程存活的单位
任务队列:存放任务的容器(常用LinkedBlockingQueue,ArrayBlockingQueue)
线程工厂:生产线程,实现接口可以自定义线程
handler:同时满足四种情况任务将会被拒绝
1线程池线程已经满了
2线程池无法扩容
3没有空闲线程,所有线程都在执行任务
4任务队列已满
拒绝的策略有四种
1默认的拒绝策略,抛出异常
2直接丢弃任务
3丢弃处于任务列头的任务,添加拒绝任务
4使用调用者线程直接执行拒绝任务

正式开发中不使用Executors创建single,fixed,cached线程池,前两者可能会在任务队列堆积大量的请求导致内存溢出,cached则是会创建大量的线程而导致内存溢出.

4两种任务提交方式execute和submit

execute是在executor接口中向线程池提交runnable任务,所以只适合提交无返回值的任务.

submit是在ExecutorService接口中,共有三个方法
submit(Runnable) 返回值Future<?> 提交Runnable任务
submit(Runnable,T) 返回值 Future 并指定执行结果
submit(Callable) Future 提交Callable任务

5.两种关闭线程池的方式shoutdown和shoutdownNow

shoutdown会延迟关闭线程池,而shoutdownNow会立即关闭线程池
shoutdown会将任务队列中的任务执行完,而shoutdonwn会将未做完的任务返回
shoutdown是的线程池状态时SHOUTDOWN
shoutdownNow状态是STOP

6.线程池状态
1running正常运行状态
2SHOUTDOWN线程池准备关闭,会处理完任务队列中的任务
3STOP不接受任务,中断正在执行的任务
4TIDYING 线程池正在关闭,线程池中的线程数为0,所有任务终止
5TERMINATED彻底关闭线程池

7线程池的常用场景(两类问题四种场景)
异步任务,资源复用
1非阻塞场景(异步消息,发邮件,刷数据),大多为io
2并发,多个耗时没有依赖关系
3定时周期,定时执行某个操作,心跳包定时发送
4线程隔离,隔离现成,hystrix降级线程

8常见坑
1cpu密集型,设置线程数大于cpu核数导致cpu耗尽
2核心链路和非核心共享线程池
3future.get()
4,参数设置

9参数设置建议
1core:io密集型:qpsMaxrtMax(10/6)利用峰值qps和rt算出并发数,并保证在线程池的60%,保证可用性
cup密集型:cpu核数±1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值