一. 算法介绍

二. 代码实现

  1. package com.wangt.java;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. import java.util.Stack;
  5. /**
  6. * @author 王天赐
  7. * @create 2019-12-11 16:44
  8. */
  9. public class LruMain {
  10. /**
  11. * 记录命中数
  12. */
  13. private static int selectPages;
  14. /**
  15. * 存储命中率
  16. */
  17. private static double selectPagesRate;
  18. /**
  19. * 内存大小
  20. */
  21. private final static int MEMORY_SIZE = 5;
  22. /**
  23. * 获取随机进程数
  24. *
  25. * @return
  26. */
  27. private static List<Integer> getProcessSeq() {
  28. // 随机页号的起始值
  29. int start = 1;
  30. // 随机页号的结束值
  31. int end = 10;
  32. List<Integer> processSeq = new ArrayList<>();
  33. for (int i = 0; i < 10; i++) {
  34. processSeq.add(randomInt(start, end));
  35. }
  36. return processSeq;
  37. }
  38. /**
  39. * 随机生成指定范围的Int类型的数
  40. *
  41. * @param start 开始值
  42. * @param end 结束值为 end - 1
  43. * @return
  44. */
  45. private static int randomInt(int start, int end) {
  46. return (int) ((Math.random() * (end - start)) + start);
  47. }
  48. /**
  49. * 打印随机生成的页面信息
  50. *
  51. * @param processSeq
  52. */
  53. public static void printPageInfo(List<Integer> processSeq) {
  54. System.out.println("<==================== [页面信息] ====================>");
  55. for (int i = 0; i < processSeq.size(); i++) {
  56. System.out.println("第" + i + "个页面号为:" + processSeq.get(i));
  57. }
  58. System.out.println("<==================== [页面信息] ====================>");
  59. System.out.println();
  60. }
  61. public static void printPageReplacementCase(Stack<Integer> pageNums) {
  62. for (int i = 0; i < 5; i++) {
  63. if (pageNums.size() > i) {
  64. System.out.print(pageNums.get(i) + " ");
  65. } else {
  66. System.out.print("0 ");
  67. }
  68. }
  69. System.out.println();
  70. }
  71. /**
  72. * 模拟 LRU 算法
  73. */
  74. public static void LRUAlgorithm() {
  75. List<Integer> processSeq = getProcessSeq();
  76. // 打印随机生成的页面信息
  77. printPageInfo(processSeq);
  78. // 用于存储已经访问的各个页面的页面号
  79. Stack<Integer> pageNums = new Stack();
  80. System.out.println("<==================== [置换信息] ====================>");
  81. for (Integer process : processSeq) {
  82. // 先判断页面是否已经调入内存
  83. if (pageNums.search(process) != -1) {
  84. // 如果页面已经存在, 则将页面调入栈顶
  85. // 1.移除该元素
  86. pageNums.remove(process);
  87. // 2.重新将数据push进栈中
  88. pageNums.push(process);
  89. // 3.页面命中数加一
  90. selectPages++;
  91. } else {
  92. // 如果页面在内存中不存在
  93. // 1.判断内存是否已满(就是栈的大小是否等于5)
  94. if (pageNums.size() < MEMORY_SIZE) {
  95. // 如果栈内元素大小小于最大值, 说明内存该没有满
  96. // 直接将页面添加进内存即可
  97. pageNums.push(process);
  98. } else {
  99. // 否则说明内存已满, 此时需要移除最近最久未使用的页面
  100. // 即栈底元素
  101. // 1.获取栈底元素
  102. Integer element = pageNums.lastElement();
  103. // 2.移除该元素
  104. pageNums.remove(element);
  105. // 3.将即将访问的页面添加进内存中(栈是用来记录访问的页面的页号)
  106. pageNums.push(process);
  107. }
  108. }
  109. printPageReplacementCase(pageNums);
  110. }
  111. System.out.println("<==================== [置换信息] ====================>");
  112. // 命中率
  113. selectPagesRate = (double) selectPages / processSeq.size();
  114. System.out.println("命中数 : " + selectPages + " 命中率 : " + selectPagesRate);
  115. }
  116. public static void main(String[] args) {
  117. LRUAlgorithm();
  118. }
  119. }