Android-线程池

10 篇文章 0 订阅

线程池

技术点

1.自定义线程池
2.ThreadPoolExecutor
3.设计模式工作线程
4.fork/join线程池

异步模式之工作线程

  让有限的工作线程轮流异步处理无限多的任务,也可以归为分工模式,典型实现就是线程池,也体现了经典设计模式中的享元模式。
  注意:不同任务类型应该使用不同的线程池,这样能够避免饥饿现象,且效率上得到合理的分配
  线程饥饿现象:本是上是出现多任务混合在同一个线程池中,如果出现相互影响的状况出现类似死锁的问题,有相互关联的相关任务不作为同一线程池处理,而是单独开辟线程池

享元设计模式

  本质:运用内存共享的原理,去有效支撑大量的细颗粒度的对象
  享元工厂,一个享元工厂,用来创建并管理对象,他主要是用来确保合理地共享对象,当用户请求一个对象时,由工厂提供一个已创建的对象示例或者创建一个
  享元对象:一个重复的对象
  使用场景:如果一个程序对于某个对象进行大量应用,且使用生命周期短,可以考虑采取享元模式进行复用。

线程数量与核心数

处理器核数:
  线程核心数是一种执行资源,资源数量就是核的个数,应用程序的线程就是服务请求数,而操作系统的作用如何调配有限的资源来服务更多的请求,这就是进程调度的概念,一般情况下,服务线程相对公平的分配到核上运行,并且在时间片上轮流使用,这就是所谓的并发执行。
  比如系统是4核,如果3个线程,分配到3个核上,8哥线程,每个核分配两个线程执行,10个线程,有些核跑3个,有些跑两个。
  所以,并非线程数量越大,速度越快,线程数量太过于庞大会导致各种内存问题,因为一个线程的开辟还会涉及到线程的上下文的应用。

问题:创建多少线程合适?
  CPU密集型运算:通常采用CPU核数+1能够实现最优的CPU利用率,+1是保证当线程由于缺页时故障或其他原因导致暂停,额外的这个线程能够顶上去,保证CPU始终周期不被浪费。

I/O密集型运算:
  CPU不总是处于繁忙状态,例如,当你执行业务计算时,这时候会使用CPU资源,但当你执行IO操作,或者远程的RPC调用时,包括进行数据库操作等,这个时候CPU会闲下来,你可以利用多线程提高他的利用率。

经验公式如下:
  线程数=核数 * 期望CPU利用率 * 总时间(CPU计算时间+等待时间)/CPU计算时间例如:4核CPU,计算时间时50%,其他等待时间是50%,期望CPU被100%利用,套用公式4*100%*100%/50%=8

ThreadPoolExecutor

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

  corePoolSize核心线程数目
  maximumPoolSize最大线程数目
  keepAliveTime生存时间-针对救急线程
  workQueue阻塞队列
  threadFactory线程工厂,可以为线程创建时起个好名字
  handler拒绝策略

在这里插入图片描述
  maxSize最大线程 - coreSize核心线程 = 救急线程
  核心线程可以1个执行1个等待,当来第5个任务的时候就会扩,产生急救线程。

在这里插入图片描述
  利用位运算合并整型变量在并发下的意义:如果两个数都是原子变量,那么合并之后,只需要对于一个原子进行CAS操作,而不是两个CAS操作

JDK中的拒绝策略

ThreadPoolExecutor自己已经提供了4个拒绝策略:
  CallerRunsPolicy:在任务被拒绝添加后,会调用当前线程池的所在的线程去执行被拒绝的任务,这个策略的缺点就是可能阻塞主线程。
  AbortPolicy:默认的拒绝策略就是AbortPolicy,直接抛出异常,抛出个RejectedExecutionException异常,也不执行这个任务了
  DiscardPolicy:这个东西什么都没干
  DiscardOldestPolicy:当任务被拒绝添加时,会抛弃任务队列中最旧的任务也就是最先加入队列的,再把这个新任务添加进去。

ThreadPoolExecutor与当前自定义的区别

1.救急线程
  性能提升
2.状态设置
  对于线程池的管理
3.原子合并
  利用位运算进行CAS的优化
4.工厂模式的应用

fork/join线程池

  fork/join时JDK1.7后加入的新的线程池实现,他主要体现的是分治思想,适用于能够进行任务拆分的CPU密集型运算,他是为了处理大数据诞生的,所谓任务拆分,是将一个大任务拆分为算法上相同的小任务,直至不能够拆分可以直接求解,跟递归相关的一些计算,如归并排序,斐波那契数列,都可以进行分治完成,fork/join在分治的基础中加入了多线程,可以把每个任务的分解和合并交给不同的线程来完成,进一步提升运算效率,fork/join默认会创建于CPU核心数大小相同的线程池,最常见业务,对于文件夹的操作。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天津 唐秙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值