`

java游戏架构那点事儿(三)

阅读更多
本节主要介绍游戏架构的核心,多线程——ThreadPoolExecutor!
线程池可以解决两个不同问题:由于减少了每个任务调用的开销,它们通常可以在执行大量异步任务时提供增强的性能,
并且还可以提供绑定和管理资源(包括执行任务集时使用的线程)的方法。每个 ThreadPoolExecutor 还维护着一些基本的统计数据,如完成的任务数。

建议程序员使用较为方便的 Executors 工厂方法
Executors.newCachedThreadPool()(无界线程池,可以进行自动线程回收)
Executors.newFixedThreadPool(int)(固定大小线程池)和
Executors.newSingleThreadExecutor()(单个后台线程)

如果手动配置和调用此类,请一定注意:
线程池类为 java.util.concurrent.ThreadPoolExecutor,其构造方法
    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              RejectedExecutionHandler handler)


corePoolSize:池中所保存的线程数,包括空闲线程。
maximumPoolSize:池中允许的最大线程数。
keepAliveTime:当线程数大于核心时,此为终止前多余的空闲线程等待新任务的最长时间。
unit:keepAliveTime参数的时间单位。
workQueue:执行前用于保持任务的队列。此队列仅保持由 execute 方法提交的Runnable 任务。
threadFactory:执行程序创建新线程时使用的工厂。
handler:由于超出线程范围和队列容量而使执行被阻塞时所使用的处理程序。

ThreadPoolExecutor的处理流程应该是这样的:

1、如果线程池大小小于corePoolSize,新建线程,处理请求
2、如果线程池大小等于corePoolSize,获取线程池中空闲的线程,处理请求
3、如果线程池大小等于corePoolSize,并且未获取到空闲的线程,则将请求放入workQueue队列,等待线程池中空闲线程处理
4、如果workQueue是个有界队列,当队列满了,如果corePoolSize< maximumPoolsize时,会尝试新建一个临时线程进行救急处理
5、如果workQueue是个有界队列,当队列满了且corePoolSize=maximumPoolsiz时,会尝试调用handler进行相应的处理
6、如果线程池中的线程数大于corePoolSize,空闲的线程会等待keepAliveTime的时间,如果无请求可处理就自行销毁

workQueue有以下几种实现:
ArrayBlockingQueue :  一个由数组支持的有界阻塞队列。此队列按 FIFO(先进先出)原则对元素进行排序。
LinkedBlockingQueue : 一个基于已链接节点的、范围任意的 blocking queue。此队列按 FIFO(先进先出)排序元素。如果未指定容量,那么容量将等于 Integer.MAX_VALUE。
PriorityBlockingQueue : 一个基于优先级堆的无界优先级阻塞队列。优先级队列的元素按照其自然顺序进行排序,或者根据构造队列时提供的 Comparator 进行排序,具体取决于所使用的构造方法。
DelayQueue:Delayed元素的一个无界阻塞队列,只有在延迟期满时才能从中提取元素。
SynchronousQueue : 一种阻塞队列,其中每个插入操作必须等待另一个线程的对应移除操作 ,反之亦然。

RejectedExecutionHandler(Runnable r, ThreadPoolExecutor executor)有以下几种处理策略:
AbortPolicy:总是抛出 RejectedExecutionException
DiscardPolicy:不执行任何操作,默认情况下它将丢弃被拒绝的任务。
DiscardOldestPolicy:放弃最旧的未处理请求,然后重试 execute;如果执行程序已关闭,则会丢弃该任务
CallerRunsPolicy:直接在execute方法的调用线程中运行被拒绝的任务;如果执行程序已关闭,则会丢弃该任务

注意:
1、如果workQueue队列是个有界队列,请一定将workQueue队列的长度设置为大于corePoolSize。因为当ThreadPoolExecutor开始工作后,请求都是通过workQueue获取的,所以当workQueueSize<corePoolSize时,corePoolSize将失去设置的意义
2、如果是计算密集型任务,建议corePoolSize=cupCount+1;如果包含IO操作或者其他阻塞操作的任务,建议corePoolSize=cupCount/密集计算所占的时间比重。当然,密集计算所占的时间比重是一个估计值,且数值在0-1之间,建议取值在0.3-0.5。
3、个人建议使用有界队列作为请求存储队列,workQueueSize=2*corePoolSize,这样设置主要是考虑运行高峰期间一个线程允许有一个等待的队列。
4、个人建议使用CallerRunsPolicy作为应急处理handler,这样可以使异步的并行处理模式临时改为单线程串行处理模式,以缓解因请求处理压力。

netty额外给我们提供了两种线程池:
MemoryAwareThreadPoolExecutor和OrderedMemoryAwareThreadPoolExecutor
MemoryAwareThreadPoolExecutor确保jvm不会因为过多的线程而导致内存溢出错误
OrderedMemoryAwareThreadPoolExecutor是前一个线程池的子类,除了保证没有内存溢出之外,还可以保证 channel event的处理次序
这两个处理器在netty4.0中已经不存在了,如果想使用请选择3.6或者更低的netty版本。
分享到:
评论

相关推荐

    Java程序员上班那点事儿

    《Java程序员上班那点事儿》这本书,正如其名,旨在揭示Java程序员在日常工作中的点滴细节,帮助初入职场或有经验的开发者更好地理解和应对工作中的挑战。书中涵盖了许多实际问题和解决方案,旨在提升读者的技能水平...

    java程序员上班那点事儿

    总的来说,“Java程序员上班那点事儿”涵盖了广泛的技能和知识领域,从基础编程到高级架构,从个人技能到团队协作,每一个环节都对他们的工作质量和效率产生深远影响。只有不断学习和实践,才能在这个快速变化的IT...

    Java程序员上班那点事儿.

    本书《Java程序员上班那点事儿》旨在为即将踏入这个领域的新人提供全面的指引,帮助他们更好地理解这个职业,并为入职后的职业生涯规划提供清晰的方向。 首先,Java是一种广泛使用的面向对象的编程语言,其强大的跨...

    Java程序员+上班那点事儿

    《Java程序员+上班那点事儿》可能提供了关于如何制定职业发展计划的建议,包括技术深造(如学习框架Spring、MyBatis等)、获取认证(如Oracle Certified Professional, Java SE 8 Programmer)以及向架构师或项目...

    java程序员的那些事儿

    让我们深入探讨一下Java程序员在日常工作中的关键知识点。 首先,学习Java编程语言是基础。Java以其“一次编写,到处运行”的特性,成为跨平台开发的首选。初学者应该掌握基本语法、面向对象编程概念(如封装、继承...

    2021互联网大厂Java架构师面试题突击视频教程

    03_关于互联网Java工程师面试突击训练课程的几点说明 04_体验一下面试官对于消息队列的7个连环炮 05_知其然而知其所以然:如何进行消息队列的技术选型? 06_引入消息队列之后该如何保证其高可用性? 07_我的天!我为...

    Java程序员+上班那点事儿 可供看看哦 你会有很大收获

    以下是一些关于Java程序员上班日常的关键知识点,这些知识将帮助你更好地理解这个职位的职责和挑战。 首先,Java语言基础是必不可少的。你需要熟悉类、对象、接口、继承、多态等核心概念,这些都是构建面向对象程序...

    《码农翻身》第二章 Java帝国.emmx

    三层架构和MVC那点事儿 Java帝国之拨云见日识回调 小张的Duck Typing JDBC的诞生 JDBC后传 一个不安分的JDBC驱动 Java帝国之 Java Bean(上) Java帝国之 Java Bean(下) Java帝国之 函数式编程(上) Java...

    大型网站技术架构:核心原理与案例分析

    关于分布式的知识点,都在这本书里面有体现,只有你想不到,没有他写不到,而且写得非常易懂,基本属于看一两遍,再记一些笔记就知道是怎么一回事儿了。多看 几遍,对分布式的理解一定会加深不少。而且里面不仅仅是...

Global site tag (gtag.js) - Google Analytics