本系统采用时间片轮转以及优先级调度算法。
概述
时间片轮转调度算法
时间片轮转调度算法主要适用于分时系统。在这种算法中,系统将所有就绪进程按到达时间的先后次序排成一个队列,进程调度程序总是选择就绪队列中第一个进程执行,即先来先服务的原则,但仅能运行一个时间片,如100ms。在使用完一个时间片后,即使进程并未完成其运行,它也必须释放出(被剥夺)处理机给下一个就绪的进程,而被剥夺的进程返回到就绪队列的末尾重新排队,等候再次运行。
优先级调度算法
优先级调度算法又称优先权调度算法,该算法既可以用于作业调度,也可以用于进程调度,该算法中的优先级用于描述作业运行的紧迫程度。
在作业调度中,优先级调度算法每次从后备作业队列中选择优先级最髙的一个或几个作业,将它们调入内存,分配必要的资源,创建进程并放入就绪队列。在进程调度中,优先级调度算法每次从就绪队列中选择优先级最高的进程,将处理机分配给它,使之投入运行。
根据新的更高优先级进程能否抢占正在执行的进程,可将该调度算法分为:
- 非剥夺式优先级调度算法。当某一个进程正在处理机上运行时,即使有某个更为重要或紧迫的进程进入就绪队列,仍然让正在运行的进程继续运行,直到由于其自身的原因而主动让出处理机时(任务完成或等待事件),才把处理机分配给更为重要或紧迫的进程。
- 剥夺式优先级调度算法。当一个进程正在处理机上运行时,若有某个更为重要或紧迫的进程进入就绪队列,则立即暂停正在运行的进程,将处理机分配给更重要或紧迫的进程。
而根据进程创建后其优先级是否可以改变,可以将进程优先级分为以下两种:
-
静态优先级。优先级是在创建进程时确定的,且在进程的整个运行期间保持不变。确定静态优先级的主要依据有进程类型、进程对资源的要求、用户要求。
-
动态优先级。在进程运行过程中,根据进程情况的变化动态调整优先级。动态调整优先级的主要依据为进程占有CPU时间的长短、就绪进程等待CPU时间的长短。
系统流程图
程序设计思路:
事实上两个算法本身都不难,难的是如何实现模拟的效果..
一开始很苦恼怎么样才能实现Jtable的实时刷新,查阅网上各大博客之后也没能成功。写完时间片流转的界面之后还是没有解决实时更新进程的问题。
直到在写优先级调度的界面的时候,我想要在开始模拟之后给用户提供添加抢占进程的按钮,以此来模拟抢占进程“抢”的过程。但是我发现,当我按下开始模拟之后,抢占的按钮居然无法点击。准确的说,当开始模拟之后,所有的按钮都无法点击了。于是我猜测是由于此时程序运行在主线程之上,而我的模拟运行逻辑其实就是造一个空循环,让currentTimeMills去做判断。当主线程被空循环困住,其它事情也就做不了了。所以我尝试开启一个新的线程来运行开始模拟。这样做之后,我发现不仅抢占的按钮可以点击,而且Jtable的数据也能够实时刷新了!于是在时间片流转那边也采用同样的方式,开启一个线程去跑模拟,实时刷新的问题就解决了。
写完这个系统,感觉对多线程有了进一步的理解。
贴一小段代码:
new Thread(()->{
while(pp.getSize()>0) {
pp.start();
ArrayList<ProcessPojo>runList=pp.getRunList();
for(ProcessPojo pcb:runList) {
Vector rows=new Vector<>();
rows.add(pcb.getName());rows.add(pcb.getState());rows.add(pcb.getNeedTime());rows.add(pcb.getCpuTime());rows.add(pcb.getOrder());
data.add(rows);
model.setDataVector(data, Title);
model.fireTableDataChanged();
table=new JTable(model);
table.validate();
table.updateUI();
}
}
System.out.println("模拟完毕.");
}).start();
效果图
主界面:提供两个算法的入口:
时间片轮转界面:输入时间片和进程数完成就绪队列的初始化.
初始化成功并开始模拟效果
优先级模拟界面:输入进程数初始化就绪队列
开始模拟并生成抢占进程效果图
本着无私奉献的精神,送上我的源代码.
各位“伸手的兄弟”,希望不要吝啬你的点赞。。