ThreadPool用法解析

线程池好像每一次参加面试的时候,都会问道,自己之前确实没有使用过什么,今天大致结合看网上博客,发现了一篇写的很好的博客,略作修改,写下
原博客地址强烈推荐这个作者写的博客,思路很清晰!!!

什么是线程池

线程池当中缓存了一定数量的线程,线程池实现了对于线程的管理和复用(最重要的就是实现对线程的复用,避免频繁创建线程和销毁线程带来的开销),当然管理的可以实现线程执行的统一分配以及调优

必须知道的线程池核心参数
  1. corePoolsize
    核心线程数 : 默认的情况下会一直存活下去(空闲的时候也存活)
  2. maximumPoolSize
    线程池所能容纳的最大线程数 : 当活动线程数到达该数值之后,后续的新任务将会阻塞
  3. keepAliveTime
    非核心线程 闲置超时时长 : 超过该时长,非核心线程会被回收(当执行alllowThreadTimeout为true的时候,keepAliveTime同时用于核心线程)
  4. unit
    指定keepAliveTiem参数的时间单位 : TimeUnit.MILLSECONDS(毫秒),TimeUnit.SECONDS(秒),TimeUnit.MINUTES(分)等等
  5. workQeue
    任务队列 : 通过线程池的execute()方法提交Runnable对象,存储在该参数中
  6. threadFactory
    线程工厂 : 为线程创建新线程

这6个参数的配置决定了线程池的作用,在创建线程池类的时候传入
ThreadPoolExecutor 是线程类的实现类,我们可以通过它实现自定义线程池

Executor executor=new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue)
}
内部逻辑原理

图片

ThreadPool使用流程
  1. 创建线程池
    创建时,通过配置线程池的参数,从而实现自己所需的线程池
                                              CORE_POOL_SIZE,
                                              MAXIMUM_POOL_SIZE,
                                              KEEP_ALIVE,
                                              TimeUnit.SECONDS,
                                              sPoolWorkQueue,
                                              sThreadFactory
                                              );
  1. 向线程池提交任务:execute()
       threadPool.execute(new Runnable() {
            @Override
            public void run() {
                ... // 线程执行任务
            }
        });```

3. 关闭线程池shutdown() 
  `threadPool.shutdown();`  
关闭线程的原理  
a. 遍历线程池中的所有工作线程  
b. 逐个调用线程的interrupt()中断线程(注:无法响应中断的任务可能永远无法终止)
也可调用shutdownNow()关闭线程:threadPool.shutdownNow() 
二者区别:  
shutdown:设置 线程池的状态 为 SHUTDOWN,然后中断所有没有正在执行任务的线程  
shutdownNow:设置线程池的状态 为 STOP,然后尝试停止所有的正在执行或暂停任务的线程,并返回等待执行任务的列表  
使用建议:一般调用shutdown()关闭线程池;若任务不一定要执行完,则调用shutdownNow()  
#### Java内部实现好了的4类功能线程池  
根据参数的不同配置,Java最常见的线程池有4类,其实这四个线程池都是通过`ThreadPoolExecutor`调整6个参数而创建而成    
1. 定长线程池(FixedThreadPool)  
2. 定时线程池(ScheduledThreadPool)  
3. 可缓存线程池(CachedThreadPool)  
4. 单线程化线程池(SingleThreadExecutor)  
##### 定长线程池(FixedThreadPool)  
1. 特点:只有核心线程 & 不会被回收、线程数量固定、任务队列无大小限制(超出的线程任务会在队列中等待)
2. 应用场景:控制线程最大并发数
3. 具体使用:通过 Executors.newFixedThreadPool() 创建  
示例:

ExecutorService fixThreadPool=Executors.newFixedThreadPool(3);//最大并发量为3
for(int i=0;i<6;i++){
final int index=i;
fixThreadPool.execute(new Runnable() {

        @Override
        public void run() {
            // TODO Auto-generated method stub
            try {
            System.out.println("当前线程"+Thread.currentThread()+"  执行任务"+index);
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    });
}

//这个程序最多只有三个线程在执行

##### 定时线程池(ScheduledThreadPool )  
1. 特点:核心线程数量固定、非核心线程数量无限制(闲置时马上回收)
2. 应用场景:执行定时 / 周期性 任务
3. 使用:通过Executors.newScheduledThreadPool()创建  
示例:

ScheduledExecutorService scheduleThreadpool=Executors.newScheduledThreadPool(3);
Runnable task=new Runnable() {

    @Override
    public void run() {
        // TODO Auto-generated method stub
        try {
            System.out.println("当前线程"+Thread.currentThread());
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
};
scheduleThreadpool.schedule(task, 1,TimeUnit.SECONDS);//延迟一秒执行任务
scheduleThreadpool.scheduleAtFixedRate(task, 10, 2000, TimeUnit.MILLISECONDS);//延迟 10ms 周期的执行
##### 可缓存线程池(CachedThreadPool)  
1. 特点:只有非核心线程、线程数量不固定(可无限大)、灵活回收空闲线程(具备超时机制,全部回收时几乎不占系统资源)、新建线程(无线程可用时)源码中显示是通过60s回收线程
2. 任何线程任务到来都会立刻执行,不需要等待
3. 应用场景:执行大量、耗时少的线程任务
使用:通过Executors.newCachedThreadPool()创建  
示例:

ExecutorService cachedThreadPool=Executors.newCachedThreadPool();
Runnable task=new Runnable() {

        @Override
        public void run() {
            // TODO Auto-generated method stub
            try {
                System.out.println("当前线程"+Thread.currentThread());
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    };
    for(int i=0;i<10;i++)
        cachedThreadPool.execute(task);  //直接创建10个线程执行      
##### 单线程化线程池(SingleThreadExecutor)  
1. 特点:只有一个核心线程(保证所有任务按照指定顺序在一个线程中执行,不需要处理线程同步的问题)
2. 应用场景:不适合并发但可能引起IO阻塞性及影响UI线程响应的操作,如数据库操作,文件操作等
3. 使用:通过Executors.newSingleThreadExecutor()创建  
示例:  

ExecutorService singleThradPool=Executors.newSingleThreadExecutor();
Runnable task=new Runnable() {

        @Override
        public void run() {
            // TODO Auto-generated method stub
            try {
                System.out.println("当前线程"+Thread.currentThread());
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    };
    for(int i=0;i<10;i++)
        singleThradPool.execute(task);//只有一个线程执行,执行完之后才执行下一个任务

“`

常见线程池 总结 & 对比

图片

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值