如果仅仅做到这一步,完成一个像Windows 3.1中的多任务系统,实际只用了一个线程,没有利用Java多线程的特点。应该注意到,虽然Java系统中线程调度与平台相关,但是相同优先级的线程之间分时运行的特点基本上是不受特定平台影响的。各个相同优先级的线程共享CPU资源,而线程又被映射成了Java语言中的Thread对象。这些对象就可以被认为是CPU资源的代表。Thread与线程执行代码主体的接口—Runnable之间是多对一的关系。一个Runnable可以被多个Thread执行。只要将Runnable的执行代码设置成上述的消息调度函数,并和消息队列对应上,那么就可以通过控制为它服务的Thread个数来决定消息队列执行的快慢,并且在运行时可以动态地新增(new)和退出Thread对象。这样就能任意调整不同消息队列在执行时所占用CPU资源的多少。至此,任何一个Java调用都可以在Thread个数不同的消息队列中选择,并可以调整这些消息队列服务的Thread个数,从而实现在运行时调整任务所占用的CPU资源。
纵观整个方案,由于仅仅基于Java语言固有的Method对象,不同任务间动态分配CPU资源并没有对任务的性质及其处理流程有任何限制,那么在消息队列中没有高优先级消息时,低优先级消息的处理函数自然会全部占用CPU资源。在不同消息队列处理速度任意设置时,并没有将特定的消息限制在快的或者慢的消息队列上。如果系统的负荷超出(比如消息队列长度超过一定限制),只要将队列中低优先级消息换出或者拒绝不能处理的消息进入,那么系统的运行就可以基本上不受负荷压力的影响,从而最大保障用户的关键业务需求。
当然,协调式多任务的思想也有其局限性,主要就是它的调度粒度比较大。系统能够保证的粒度是一次消息处理过程。如果消息处理逻辑非常费时,那么编程人员就必须再处理函数内部,让系统主动让出CPU资源。这虽然需要在处理消息响应逻辑时增加一个考虑因素,但是,在Windows系统盛行的今天,这是一个已经被普遍接受的思路。由于方案中并没有局限为消息队列服务的线程数目,所以一个长时间的消息响应只会影响一个线程,而不会对整个系统产生致命的影响。除了调度粒度的问题以外,还有访问消息队列操作在各个线程间互斥的问题。取出消息的过程是串行化的,因此对于这一瓶颈的解决方案就是:假设取出一条消息的操作相对于处理消息的消耗可以忽略不计,那么对于多次调用且仅有两三行响应逻辑的消息,编程人员通过函数调用就可以直接执行。
文章来源于领测软件测试网 https://www.ltesting.net/