多线程基础---线程池

目录

1. 作用

2. 创建线程池时对于其中参数的理解

3. 线程池执行流程

4. 阻塞队列的实现类

5. 快捷方式创建线程池

6. 不能使用快捷方式创建线程池,为什么?

7. 4种拒绝策略:

8. 关闭线程池


1. 作用

       线程的创建和销毁,都是比较消耗资源,代价比较大的.然而池,可以实现,不用反复创建对象,可以复用.

2. 创建线程池时对于其中参数的理解

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

       corePoolSize: 核心线程数

       maximumPoolSize: 最大线程数

       keepAliveTime: 空闲时间数量

       unit: 空闲时间单位

       workQueue: 阻塞/任务/工作队列

       threadFactory: 线程创建的工厂

       handler: 拒绝策略

3. 线程池执行流程

       根据上图场景,我们可以将自己想象成快递站的老板,试想一下,假如此时一有人过来寄东西了,那我就雇佣一个临时工,等处理完了,立马就将他解雇,可以是可以,但是好像不太划算,毕竟频繁的雇佣解雇临时工开销开始比较大的.

       灵机一动,我决定按照自己店里的实际需要,聘请 3 位正式员工,要是他们仨都忙着,那我就将要寄出的包裹先放在我的小店里,等他们三个将手里的包裹处理完了之后,就继续处理小店里堆积的包裹,开销也不是很大,日子过的云淡风轻~

       但是没想到,618活动来的让我措手不及,很快我的小店就堆满了,三个正式员工也处理不过来,那这个时候还有人来寄包裹可怎么办,不能伤了寄件人的心呀~为了展示我们的实力,小店虽小,还是能多站下几个人的,不要慌,我再雇佣临时工不就好了嘛,场地限制,我的店里最多只能站6个人,也就是我最多同时只能雇3个临时工,这下舒坦了.

       但是好日子没几天,还是我太稚嫩,低估了消费者的实力,很快,包裹堆满了小店,看着他们六个人忙的不可开交,我也是心疼,此时,还有源源不断的人来寄包裹,这下,我是真的没有办法啦,该伤的心还是得伤,心有余而力不足,只好拒绝并告知他们另寻他处吧~

       当完老板再留恋不舍也要缓过神来呀,再对照上面流程图理解一下线程池吧~核心线程对应到的是3个正式员工,阻塞队列对应到快递小店的存储包裹区,线程池对应到小店的前台(最多能站6个人).

4. 阻塞队列的实现类

1) 数组的实现,指定容量

       public ArrayBlockingQueue<>(int capacity){...

2) 链表的实现,无边界或指定容量

       public LinkedBlockingQueue<>(){.. //无边界

       public LinkedBlockingQueue<>(int capacity){...//指定容量

5. 快捷方式创建线程池

ExecutorService single=Executors.newSingleThreadExecutor();
ExecutorService fixed=Executors.newFixedThreadPool(4);
ExecutorService catched=Executors.newCachedThreadPool();
ScheduledExecutorService scheduled=Executors.newScheduledThreadPool(4);

6. 不能使用快捷方式创建线程池,为什么?

       ① 阻塞队列都是无边界的,如果提交任务的速度快于执行任务的速度(相当于生产者消费者模型中生产>消费),队列中保存的任务会越来越多,java进程的内存占用越来越多,OOM(内存溢出,java进程挂掉)

       ② 没有提供拒绝策略,会使用默认的抛异常的方式拒绝.一般来说,任务在线程池无法处理的情况下,也不能直接丢弃,需要记录(一般记录为日志,数据库,其他地方).

7. 4种拒绝策略:

       AbortPolicy()  //直接抛出异常(默认采用此策略)

       CallerRunsPolicy()  //只用调用者所在线程来运行任务,即谁让我执行任务/谁提交的任务,就让谁去执行(提交任务的线程)

       DiscardPolicy()  //丢弃提交的任务

       DiscardOldestPolicy()  //丢弃队列里最近(最旧)的一个任务,并执行当前任务.

8. 关闭线程池

1) 使用的API

       可以通过调用线程池的shutdown或shutdownNow方法来关闭线程池。它们的原理是遍历线程池中的工作线程,然后逐个调用线程的interrupt方法来中断线程(是否要中断,任务代码自行决定),所以无法响应中断的任务可能永远无法终止。但是它们存在一定的区别。

       shutdownNow首先将线程池的状态设置成STOP,然后尝试停止所有的正在执行或暂停任务的线程,并返回等待执行任务的列表

       shutdown只是将线程池的状态设置成SHUTDOWN状态,然后中断所有没有正在执行任务的线程

 

  • 23
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 33
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值