Java的线程虽然在编程角度(API)是与平台无关的但它的运行效果却和不同操作系统平台密切相关为了利用更多的CPU资源Java中的一个线程 (Thread)就对应着不同操作系统下的一个真实线程因为Java虚拟机没有实现线程的调度所以这些Java的线程在不同操作系统调度下运行的差异性也就比较明显例如在Windows系统中不仅线程的优先级少于Java API参数规定的十个优先级而且微软明确反对程序员动态调整线程优先级即使在操作系统中有足够的优先权让线程优先级的参数和真实线程的优先级对应不同操作系统的调度方式也会有许多不同这最终会造成代码在不同平台上的行为变得不可预测这就很难满足复杂的大规模并发任务的众多优先级需求从而很难达到用户业务需要达到的效果
由于在Java系统中线程被包装在一个Java语言的对象类—Thread中所以为了完成Java语言对象和操作系统线程的对应Java线程的系统开销还是比较大的(在NT 中平均每个线程大致占用KB内存)因此如果让Thread对象个数和成千上万的任务数同比例增长就显然是不合理的
综上所述根据并发多任务的大规模需求和Java平台固有的特点想要利用Java Thread对象的优先级调整CPU资源的分配是非常困难的所以应该尽量避免让线程和任务直接对应也尽量避免使用操作系统线程优先级的调度机制
解决方案
根据以上分析问题的症结在于多任务系统中的任务在Java语言中的对应以及任务间的相互调度
从本质上看一个任务就是一系列对象方法的调用序列与Java的Thread对象或者别的类的对象没有必然联系在避免使用不同操作系统线程调度且同时Java虚拟机又没有线程调度能力的情况下要想构造一个协调式多任务系统让各个任务相互配合就成了最直接的思路协调式多任务系统一般有以下特点
任务由消息驱动消息的响应代码完成任务逻辑的处理;
消息队列完成消息的存储和管理从而利用消息处理的次序体现任务优先级的不同;
任务中耗时的消息响应逻辑能够主动放弃CPU资源让别的任务执行(像Windows 中的Yield函数Visual Basic中的DoEvents语句)
可能出于巧合Java语言具有构造协调式多任务系统天然的条件Java对象的方法不仅是一个函数调用它还是一个javalangreflectMethod类的对象而所有对象的方法都可以通过Method类的invoke 方法调用如果能使每个任务所对应的一系列方法全部以对象形式包装成消息放到消息队列中然后再按照自己的优先级算法将队列中的消息取出执行其 Method对象的invoke调用那么一个基本的协调式多任务系统就形成了其中任务的优先级和线程的优先级没有绑定关系该系统的主体调度函数可以设置成一个死循环按照需要的优先级算法处理消息队列对于有多重循环外设等待等耗时操作的消息响应函数可以在响应函数内部递归调用主体调度函数这一次调用把原来的死循环改成在消息队列长度减少到一定程度(或者为空)后退出退出后函数返回执行刚才没有完成的消息响应逻辑这样就非常自然地实现了协调式系统中任务主动放弃CPU资源的要求
[] [] []