一. Clock 算法介绍
二. 改进型Clock算法介绍
2.1 介绍
2.2 代码实现
package com.wangt.java;import java.util.*;/** * @author 王天赐 * @create 2019-12-11 20:27 */public class ClockProMain { /** * 记录命中数 */ private static int selectPages; /** * 存储命中率 */ private static double selectPagesRate; /** * 内存大小 */ private final static int MEMORY_SIZE = 5; /** * 获取随机进程数 * @return */ private static List<Integer> getProcessSeq(){ // 随机页号的起始值 int start = 1; // 随机页号的结束值 int end = 10; List<Integer> processSeq = new ArrayList<>(); for (int i = 0; i < 10; i++) { processSeq.add(randomInt(start, end)); } return processSeq; } /** * 随机生成指定范围的Int类型的数 * @param start 开始值 * @param end 结束值为 end - 1 * @return */ private static int randomInt(int start , int end){ return (int)((Math.random() * (end - start)) + start); } /** * 打印随机生成的页面信息 * @param processSeq */ public static void printPageInfo(List<Integer> processSeq){ System.out.println("<==================== [页面信息] ====================>"); for (int i = 0; i < processSeq.size(); i++) { System.out.println("第" + i +"个页面号为:" + processSeq.get(i)); } System.out.println("<==================== [页面信息] ====================>"); System.out.println(); } public static void printPageReplacementCase(List<Integer> memory){ for (int i = 0; i < 5; i++) { if (memory.size() > i) { System.out.print(memory.get(i) + " "); } else { System.out.print("0 "); } } System.out.println(); } /** * 第一轮页面扫描 * @param memory * @return */ public static Integer firstRoundScan(Map<Integer,Page> memory){ // 要被淘汰的页号 Integer pageNum = -1; for (Map.Entry<Integer, Page> kv : memory.entrySet()) { Page page = kv.getValue(); if(page.getVisit() == 0 && page.getEdit() == 0){ pageNum = kv.getKey(); break; } } return pageNum; } /** * 第二轮页面扫描 * @param memory * @return */ public static Integer secondRoundScan(Map<Integer,Page> memory){ // 要被淘汰的页号 Integer pageNum = -1; for (Map.Entry<Integer, Page> kv : memory.entrySet()) { Page page = kv.getValue(); // 如果寻找到 访问位为 0, 编辑为 1的页面,则停止扫描 if(page.getVisit() == 0 && page.getEdit() == 1){ pageNum = kv.getKey(); break; }else{ // 第二遍扫描将访问位置为 0 page.setVisit(0); } } return pageNum; } public static void main(String[] args) { List<Integer> processes = getProcessSeq(); Map<Integer,Page> pages = new HashMap<>(); List<Integer> memory = new ArrayList<>(); // 打印随机生成的页面信息 printPageInfo(processes); for (Integer process : processes) { // 判断内存中是否有该页面 if(pages.get(process) == null){ // 如果返回值等于null, 则说明内存中没有该页面 // 此时判断内存是否已满 if(memory.size() < MEMORY_SIZE){ // 如果内存没有满, 则直接添加即可 // 该页面访问位置为 0 , 编辑为设置为 0 memory.add(process); pages.put(process, new Page(process,1,0)); }else{ // 如果内存已满, 则需要换出页面 // 换出策略 : V 表示访问位, E表示编辑位, 0 表示未访问, 1表示已访问/已编辑 // V:0 ,E:0 // V:0 ,E:1 // V:1 ,E:0 // V:1 ,E:1 // 记录需要移除的页号 Integer removePageNum = -1; do { // 第一轮扫描 : 查询 => 访问位=0,编辑位=0 的页面号 if ((removePageNum = firstRoundScan(pages)) == -1) { // 第二轮扫描 : 查询 => 访问位=0,编辑位 =1的页面, 并且将扫描过的页面的访问位置为0 removePageNum = secondRoundScan(pages); }else { break; } // 第三轮扫描 : 重复上述过程 // 提示 如果都是 访问位=1,编辑位=0, 在进行第二轮扫描后, 都会变成 0,0 ! }while (removePageNum == -1); // 移除需要淘汰的进程号 memory.remove(removePageNum); pages.remove(removePageNum); // 将置换的页面添加进主存中 memory.add(process); pages.put(process, new Page(process,1,0)); } }else{ // 命中数加一 selectPages++; } // 打印页面置换情况 printPageReplacementCase(memory); } }}class Page{ // 页号 private Integer pageNumber; // 访问位 private Integer visit; // 修改位 private Integer edit; public Page() { } public Page(Integer pageNumber, Integer visit, Integer edit) { this.pageNumber = pageNumber; this.visit = visit; this.edit = edit; } public Integer getPageNumber() { return pageNumber; } public void setPageNumber(Integer pageNumber) { this.pageNumber = pageNumber; } public Integer getVisit() { return visit; } public void setVisit(Integer visit) { this.visit = visit; } public Integer getEdit() { return edit; } public void setEdit(Integer edit) { this.edit = edit; }}