blocked Queue

本文介绍了几种常用的阻塞队列,包括ArrayBlockingQueue、LinkedBlockingQueue及ConcurrentLinkedQueue等。详细探讨了它们的特点和使用场景,以及核心接口的操作方法。

有几种blocked Queue
系统开发中,经常会用到 阻塞型的容器,适合于实现“消费者生产者”模式

转发

类图介绍

这里写图片描述

核心接口

放入数据

  • offer(anObject): 非阻塞, 表示如果可能的话,如可容纳,return true;
  • offer(E o, long timeout, TimeUnit unit), 阻塞+超时;
  • put(anObject): 一直阻塞;

获取数据

  • poll(time): 阻塞+超时, 取走首位的对象
  • take(): 一直阻塞, 取走排在首位的对象;
  • drainTo(): 批量获取所有可用的数据对象(还可以指定获取数据的个数), 提升获取数据效率;不需要多次分批加锁或释放锁。

ArrayBlockingQueue

LinkedBlockingQueue

它对头和尾(取和添加操作)采用两把不同的锁,相对于ArrayBlockingQueue提高了吞吐量

ConcurrentLinkedQueue

是一个无锁的queue实现,它采用了一种无锁算法(在API中有说明),相比于传统的同步的queue来说吞吐量可以大大提高,同时它也不同于BlockingQueue,并不单单提供阻塞操作。它主要的目的是通过采用无锁的算法,使得read/write操作均不需要对容器加锁,提高容器吞吐量

import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.LinkedList; import java.util.Queue; import java.util.Random; import java.util.ArrayList; import java.util.List; // 进程节点类 class ProcessNode { int id; String name; ProcessNode left; ProcessNode right; int x, y; // 用于绘制的坐标 Color color; String status; // 进程状态: READY, RUNNING, BLOCKED int resources; // 持有的资源数量 int requestedResources; // 请求的资源数量 public ProcessNode(int id, String name) { this.id = id; this.name = name; this.left = null; this.right = null; this.color = Color.BLUE; this.status = "READY"; this.resources = 0; this.requestedResources = 0; } } // 资源管理器类(信号量) class ResourceManager { private int availableResources; private int availableCPU; // CPU数量 private Queue<ProcessNode> blockedQueue; // 阻塞队列 private Queue<ProcessNode> readyQueue; // 就绪队列(FCFS队列) private List<ProcessNode> runningQueue; // 运行队列 private Random random; public ResourceManager(int initialResources) { this.availableResources = initialResources; this.availableCPU = 1; // 只有1个CPU this.blockedQueue = new LinkedList<>(); this.readyQueue = new LinkedList<>(); // FCFS队列 this.runningQueue = new ArrayList<>(); this.random = new Random(); } // 添加进程时消耗资源 public synchronized boolean addProcess(ProcessNode process) { // P0节点不需要资源,直接添加到树中但不加入队列 if (process.id == 0) { System.out.println("Process P0 added to tree only (no resources consumed)"); return true; } // 每个进程需要1个资源 int requiredResources = 1; if (availableResources >= requiredResources) { availableResources -= requiredResources; process.resources += requiredResources; // 添加到就绪队列队尾(FCFS) readyQueue.add(process); process.status = "READY"; process.color = Color.BLUE; System.out.println("Process " + process.name + " added successfully. Consumed 1 resource. Available resources: " + availableResources); // 尝试分配CPU allocateCPU(); return true; } else { // 资源不足,直接进入阻塞队列队尾 blockedQueue.add(process); process.status = "BLOCKED"; process.color = Color.RED; System.out.println("Process " + process.name + " blocked when adding. Available resources: " + availableResources); return false; } } // 分配CPU给就绪队列中的进程(FCFS) private synchronized void allocateCPU() { if (availableCPU > 0 && !readyQueue.isEmpty()) { // 有可用CPU且就绪队列不为空,从队首取进程(FCFS) ProcessNode process = readyQueue.poll(); // 获取并移除就绪队列的第一个进程 runningQueue.add(process); availableCPU--; process.status = "RUNNING"; process.color = Color.GREEN; System.out.println("CPU allocated to " + process.name + " (FCFS). Available CPU: " + availableCPU); } } // P操作 - 申请资源 public synchronized boolean requestResource(ProcessNode process, int resources) { // P0节点不参与资源申请 if (process.id == 0) { System.out.println("Process P0 does not participate in resource requests"); return true; } process.requestedResources = resources; if (availableResources >= resources) { availableResources -= resources; process.resources += resources; System.out.println("Process " + process.name + " successfully requested " + resources + " resources"); return true; } else { // 当前进程需要阻塞 if (runningQueue.contains(process)) { // 如果是运行中的进程,释放CPU runningQueue.remove(process); availableCPU++; System.out.println("Process " + process.name + " released CPU due to resource blocking"); } readyQueue.remove(process); // 添加到阻塞队列队尾 if (!blockedQueue.contains(process)) { blockedQueue.add(process); } process.status = "BLOCKED"; process.color = Color.RED; System.out.println("Process " + process.name + " blocked when requesting " + resources + " resources. Available: " + availableResources); // 释放的CPU可以分配给其他就绪进程 allocateCPU(); return false; } } // V操作 - 释放资源 public synchronized void releaseResource(ProcessNode process, int resources) { // P0节点不参与资源释放 if (process.id == 0) { System.out.println("Process P0 does not participate in resource release"); return; } availableResources += resources; process.resources -= resources; System.out.println("Process " + process.name + " released " + resources + " resources. Now available: " + availableResources); // 检查阻塞队列 checkBlockedQueue(); } // 进程完成运行,释放CPU,转入就绪队列队尾 public synchronized void processCompleted(ProcessNode process) { // P0节点不参与运行 if (process.id == 0) { System.out.println("Process P0 does not participate in CPU running"); return; } if (runningQueue.contains(process)) { // 释放CPU runningQueue.remove(process); availableCPU++; System.out.println("Process " + process.name + " completed. Released CPU. Available CPU: " + availableCPU); // 转入就绪队列队尾 readyQueue.add(process); process.status = "READY"; process.color = Color.BLUE; System.out.println("Process " + process.name + " moved to ready queue tail"); // 尝试分配CPU给其他就绪进程 allocateCPU(); } // 检查阻塞队列(因为可能释放了资源) checkBlockedQueue(); } // 检查阻塞队列 - 优化的版本 private synchronized void checkBlockedQueue() { if (blockedQueue.isEmpty()) { return; } // 创建一个临时队列来存放仍然需要等待的进程 Queue<ProcessNode> stillBlocked = new LinkedList<>(); // 遍历阻塞队列,尝试唤醒可以运行的进程 while (!blockedQueue.isEmpty()) { ProcessNode blockedProcess = blockedQueue.poll(); // 检查是新添加的阻塞进程还是资源请求阻塞的进程 int requiredResources = (blockedProcess.resources == 0) ? 1 : blockedProcess.requestedResources; if (availableResources >= requiredResources) { // 有足够资源,唤醒进程到就绪队列队尾 availableResources -= requiredResources; blockedProcess.resources += requiredResources; // 移动到就绪队列队尾(FCFS) readyQueue.add(blockedProcess); blockedProcess.status = "READY"; blockedProcess.color = Color.BLUE; if (blockedProcess.resources == 1) { System.out.println("Waking up new process " + blockedProcess.name + " with 1 resource, moved to ready queue tail"); } else { System.out.println("Waking up process " + blockedProcess.name + " with " + blockedProcess.requestedResources + " resources, moved to ready queue tail"); } } else { // 仍然没有足够资源,保持阻塞 stillBlocked.add(blockedProcess); } } // 将仍然阻塞的进程放回阻塞队列 blockedQueue = stillBlocked; // 尝试分配CPU给新唤醒的就绪进程 allocateCPU(); } // 节点删除时释放其资源 public synchronized void releaseAllResources(ProcessNode process) { // P0节点没有资源 if (process.id == 0) { System.out.println("Process P0 deleted (no resources to release)"); } else if (process.resources > 0) { availableResources += process.resources; System.out.println("Process " + process.name + " deleted, released all " + process.resources + " resources"); process.resources = 0; } // 如果是运行中的进程,释放CPU if (runningQueue.contains(process)) { runningQueue.remove(process); availableCPU++; System.out.println("Process " + process.name + " released CPU due to deletion"); } // 从所有队列中移除该进程 readyQueue.remove(process); runningQueue.remove(process); blockedQueue.remove(process); // 检查是否可以唤醒其他进程并分配CPU checkBlockedQueue(); allocateCPU(); } // 强制进程下CPU(用于防止进程霸占CPU) public synchronized void forceProcessOffCPU(ProcessNode process) { // P0节点不参与运行 if (process.id == 0) { System.out.println("Process P0 does not participate in CPU running"); return; } if (runningQueue.contains(process)) { // 释放CPU runningQueue.remove(process); availableCPU++; // 随机决定进程去向:50%概率进入阻塞队列,50%概率进入就绪队列 if (random.nextBoolean()) { // 进入阻塞队列队尾 blockedQueue.add(process); process.status = "BLOCKED"; process.color = Color.RED; System.out.println("Process " + process.name + " forced off CPU to blocked queue (random decision)"); } else { // 进入就绪队列队尾 readyQueue.add(process); process.status = "READY"; process.color = Color.BLUE; System.out.println("Process " + process.name + " forced off CPU to ready queue tail (random decision)"); } // 尝试分配CPU给其他就绪进程 allocateCPU(); } } // 运行进程下CPU后释放资源 public synchronized void releaseResourceFromRunningProcess(ProcessNode process, int resources) { if (runningQueue.contains(process)) { // 释放CPU runningQueue.remove(process); availableCPU++; // 释放资源 availableResources += resources; process.resources -= resources; // 转入就绪队列队尾 readyQueue.add(process); process.status = "READY"; process.color = Color.BLUE; System.out.println("Process " + process.name + " released " + resources + " resources and moved to ready queue tail. Available resources: " + availableResources); // 检查阻塞队列并分配CPU checkBlockedQueue(); allocateCPU(); } } public int getAvailableResources() { return availableResources; } public int getAvailableCPU() { return availableCPU; } public int getBlockedCount() { return blockedQueue.size(); } public int getReadyCount() { return readyQueue.size(); } public int getRunningCount() { return runningQueue.size(); } public List<ProcessNode> getReadyQueue() { return new ArrayList<>(readyQueue); } public List<ProcessNode> getRunningQueue() { return new ArrayList<>(runningQueue); } public Queue<ProcessNode> getBlockedQueue() { return new LinkedList<>(blockedQueue); } } // 支持中文字体的二叉树面板 class BinaryTreePanel extends JPanel { ProcessNode root; private ResourceManager resourceManager; private Random random; int processId; private Font chineseFont; public BinaryTreePanel() { this.root = null; this.resourceManager = new ResourceManager(3); // 初始3个资源 this.random = new Random(); this.processId = 0; // 从0开始 // 设置支持中文的字体 chineseFont = createChineseFont(); setBackground(Color.WHITE); setLayout(new BorderLayout()); } // 创建支持中文的字体 private Font createChineseFont() { String[] fontNames = { "Microsoft YaHei", "SimHei", "SimSun", "KaiTi", "Arial Unicode MS", "Dialog", "SansSerif" }; for (String fontName : fontNames) { Font font = new Font(fontName, Font.PLAIN, 12); if (font.canDisplay('中')) { return font; } } return new Font("Dialog", Font.PLAIN, 12); } // 插入节点 - 修改为消耗资源 public void insertNode(int id, String name) { ProcessNode newNode = new ProcessNode(id, name); // 先添加到树中 root = insertRecursive(root, newNode); // 然后尝试添加到资源管理器(P0不加入队列) if (id != 0) { resourceManager.addProcess(newNode); } calculatePositions(); repaint(); } private ProcessNode insertRecursive(ProcessNode current, ProcessNode newNode) { if (current == null) { return newNode; } // 随机选择插入左子树或右子树 if (random.nextBoolean()) { current.left = insertRecursive(current.left, newNode); } else { current.right = insertRecursive(current.right, newNode); } return current; } // 删除随机节点 public void deleteRandomNode() { if (root == null) { JOptionPane.showMessageDialog(this, "树为空,无法删除节点"); return; } ProcessNode nodeToDelete = getRandomNode(root); if (nodeToDelete != null) { deleteNodeAndChildren(nodeToDelete.id); } } // 删除指定ID的节点及其所有子节点 public void deleteNodeAndChildren(int id) { if (root == null) { JOptionPane.showMessageDialog(this, "树为空,无法删除节点"); return; } ProcessNode nodeToDelete = findNodeById(root, id); if (nodeToDelete != null) { // 递归释放该节点及其所有子节点的资源 releaseNodeAndChildrenResources(nodeToDelete); // 从树中删除该节点及其所有子节点 root = deleteNodeAndChildrenRecursive(root, nodeToDelete); calculatePositions(); repaint(); System.out.println("删除节点及其子节点: " + nodeToDelete.name + " (ID: " + id + ")"); JOptionPane.showMessageDialog(this, "成功删除节点及其子节点: " + nodeToDelete.name + " (ID: " + id + ")"); } else { JOptionPane.showMessageDialog(this, "未找到ID为 " + id + " 的节点"); } } // 递归释放节点及其所有子节点的资源 private void releaseNodeAndChildrenResources(ProcessNode node) { if (node == null) return; // 释放当前节点的资源 resourceManager.releaseAllResources(node); // 递归释放左子树资源 releaseNodeAndChildrenResources(node.left); // 递归释放右子树资源 releaseNodeAndChildrenResources(node.right); } // 递归删除节点及其所有子节点 private ProcessNode deleteNodeAndChildrenRecursive(ProcessNode root, ProcessNode nodeToDelete) { if (root == null) return null; if (root == nodeToDelete) { // 返回null表示删除整个子树 return null; } // 递归在左右子树中查找并删除 root.left = deleteNodeAndChildrenRecursive(root.left, nodeToDelete); root.right = deleteNodeAndChildrenRecursive(root.right, nodeToDelete); return root; } // 根据ID查找节点 private ProcessNode findNodeById(ProcessNode node, int id) { if (node == null) { return null; } if (node.id == id) { return node; } ProcessNode leftResult = findNodeById(node.left, id); if (leftResult != null) { return leftResult; } return findNodeById(node.right, id); } // 随机生成节点 public void generateRandomNodes(int count) { for (int i = 0; i < count; i++) { // 进程名称与ID对应,例如ID=0 -> P0, ID=1 -> P1 insertNode(processId, "P" + processId); processId++; // 插入后再递增 } calculatePositions(); repaint(); } // 清空所有节点 public void clearAllNodes() { // 释放所有节点的资源 if (root != null) { releaseAllResourcesRecursive(root); } root = null; processId = 0; // 重置为0 repaint(); } private void releaseAllResourcesRecursive(ProcessNode node) { if (node == null) return; resourceManager.releaseAllResources(node); releaseAllResourcesRecursive(node.left); releaseAllResourcesRecursive(node.right); } private int countNodes(ProcessNode node) { if (node == null) return 0; return 1 + countNodes(node.left) + countNodes(node.right); } // 获取所有节点的ID列表(用于用户选择) public List<Integer> getAllNodeIds() { List<Integer> ids = new ArrayList<>(); collectNodeIds(root, ids); return ids; } private void collectNodeIds(ProcessNode node, List<Integer> ids) { if (node == null) return; ids.add(node.id); collectNodeIds(node.left, ids); collectNodeIds(node.right, ids); } // 计算节点位置 private void calculatePositions() { if (root == null) return; int levelHeight = 80; int startX = getWidth() / 2; int startY = 120; calculatePositionRecursive(root, startX, startY, Math.max(200, getWidth() / 4), levelHeight, 0); } private void calculatePositionRecursive(ProcessNode node, int x, int y, int offsetX, int levelHeight, int level) { if (node == null) return; node.x = x; node.y = y; if (node.left != null) { calculatePositionRecursive(node.left, x - offsetX, y + levelHeight, offsetX / 2, levelHeight, level + 1); } if (node.right != null) { calculatePositionRecursive(node.right, x + offsetX, y + levelHeight, offsetX / 2, levelHeight, level + 1); } } private int getHeight(ProcessNode node) { if (node == null) return 0; return 1 + Math.max(getHeight(node.left), getHeight(node.right)); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g; g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // 绘制资源信息和队列状态 drawResourceAndQueueInfo(g2d); // 绘制树 if (root != null) { drawTree(g2d, root); } // 绘制队列可视化 drawQueueVisualization(g2d); } private void drawResourceAndQueueInfo(Graphics2D g2d) { g2d.setColor(Color.BLACK); g2d.setFont(chineseFont.deriveFont(Font.BOLD, 16)); // 资源信息 g2d.drawString("可用资源: " + resourceManager.getAvailableResources(), 20, 30); g2d.drawString("可用CPU: " + resourceManager.getAvailableCPU(), 20, 55); // 队列统计信息 g2d.setFont(chineseFont.deriveFont(Font.BOLD, 14)); g2d.setColor(Color.BLUE); g2d.drawString("就绪队列: " + resourceManager.getReadyCount(), 200, 30); g2d.setColor(Color.GREEN); g2d.drawString("运行队列: " + resourceManager.getRunningCount(), 350, 30); g2d.setColor(Color.RED); g2d.drawString("阻塞队列: " + resourceManager.getBlockedCount(), 500, 30); g2d.setColor(Color.BLACK); g2d.drawString("总进程数: " + (root != null ? countNodes(root) : 0), 650, 30); // 显示下一个进程ID g2d.drawString("下一个进程ID: " + processId, 800, 30); } private void drawTree(Graphics2D g2d, ProcessNode node) { if (node == null) return; // 绘制连接线 if (node.left != null) { g2d.setColor(Color.GRAY); g2d.drawLine(node.x, node.y, node.left.x, node.left.y); drawTree(g2d, node.left); } if (node.right != null) { g2d.setColor(Color.GRAY); g2d.drawLine(node.x, node.y, node.right.x, node.right.y); drawTree(g2d, node.right); } // 绘制节点 g2d.setColor(node.color); g2d.fillOval(node.x - 25, node.y - 25, 50, 50); g2d.setColor(Color.WHITE); g2d.setFont(chineseFont.deriveFont(Font.BOLD, 12)); // 绘制节点信息 String nodeInfo = node.name; FontMetrics fm = g2d.getFontMetrics(); int textWidth = fm.stringWidth(nodeInfo); g2d.drawString(nodeInfo, node.x - textWidth / 2, node.y - 8); // 绘制状态和资源 g2d.setFont(chineseFont.deriveFont(Font.PLAIN, 10)); String statusInfo = node.status + "(" + node.resources + ")"; textWidth = fm.stringWidth(statusInfo); g2d.drawString(statusInfo, node.x - textWidth / 2, node.y + 5); // 绘制ID String idInfo = "ID:" + node.id; textWidth = fm.stringWidth(idInfo); g2d.drawString(idInfo, node.x - textWidth / 2, node.y + 18); } private void drawQueueVisualization(Graphics2D g2d) { int panelHeight = getHeight(); int queueStartY = panelHeight - 150; int boxHeight = 30; int boxWidth = 60; int spacing = 10; // 绘制就绪队列 g2d.setColor(Color.BLUE); g2d.setFont(chineseFont.deriveFont(Font.BOLD, 14)); g2d.drawString("就绪队列 (" + resourceManager.getReadyCount() + "):", 50, queueStartY - 10); int xPos = 50; for (ProcessNode process : resourceManager.getReadyQueue()) { g2d.setColor(Color.BLUE); g2d.fillRect(xPos, queueStartY, boxWidth, boxHeight); g2d.setColor(Color.WHITE); g2d.drawString(process.name, xPos + 15, queueStartY + 20); xPos += boxWidth + spacing; } // 绘制运行队列 g2d.setColor(Color.GREEN); g2d.drawString("运行队列 (" + resourceManager.getRunningCount() + "):", 50, queueStartY + 50); xPos = 50; for (ProcessNode process : resourceManager.getRunningQueue()) { g2d.setColor(Color.GREEN); g2d.fillRect(xPos, queueStartY + 60, boxWidth, boxHeight); g2d.setColor(Color.WHITE); g2d.drawString(process.name, xPos + 15, queueStartY + 80); xPos += boxWidth + spacing; } // 绘制阻塞队列 g2d.setColor(Color.RED); g2d.drawString("阻塞队列 (" + resourceManager.getBlockedCount() + "):", 50, queueStartY + 110); xPos = 50; for (ProcessNode process : resourceManager.getBlockedQueue()) { g2d.setColor(Color.RED); g2d.fillRect(xPos, queueStartY + 120, boxWidth, boxHeight); g2d.setColor(Color.WHITE); g2d.drawString(process.name, xPos + 15, queueStartY + 140); xPos += boxWidth + spacing; } } // 随机选择一个节点进行操作 public void performRandomOperation() { if (root == null) { JOptionPane.showMessageDialog(this, "树为空,请先添加节点"); return; } ProcessNode randomNode = getRandomNode(root); if (randomNode == null) return; // P0节点不参与操作 if (randomNode.id == 0) { System.out.println("P0节点不参与资源操作"); return; } int operation = random.nextInt(4); // 0: 申请资源, 1: 释放资源, 2: 完成运行, 3: 下CPU释放资源 if (operation == 0) { // 申请1-3个资源 int requestedResources = random.nextInt(3) + 1; resourceManager.requestResource(randomNode, requestedResources); } else if (operation == 1) { // 释放资源(如果有的话) if (randomNode.resources > 0) { int releasedResources = Math.min(randomNode.resources, random.nextInt(randomNode.resources) + 1); resourceManager.releaseResource(randomNode, releasedResources); } else { // 如果没有资源,就申请资源 int requestedResources = random.nextInt(3) + 1; resourceManager.requestResource(randomNode, requestedResources); } } else if (operation == 2) { // 完成运行(如果是运行中的进程) if (randomNode.status.equals("RUNNING")) { resourceManager.processCompleted(randomNode); } else { // 如果不是运行中的进程,就申请资源 int requestedResources = random.nextInt(3) + 1; resourceManager.requestResource(randomNode, requestedResources); } } else { // 运行进程下CPU并释放资源 if (randomNode.status.equals("RUNNING") && randomNode.resources > 0) { int releasedResources = Math.min(randomNode.resources, random.nextInt(randomNode.resources) + 1); resourceManager.releaseResourceFromRunningProcess(randomNode, releasedResources); } else if (randomNode.status.equals("RUNNING")) { // 如果没有资源,就完成运行 resourceManager.processCompleted(randomNode); } else { // 如果不是运行中的进程,就申请资源 int requestedResources = random.nextInt(3) + 1; resourceManager.requestResource(randomNode, requestedResources); } } repaint(); } private ProcessNode getRandomNode(ProcessNode node) { if (node == null) return null; // 使用BFS随机选择一个节点 Queue<ProcessNode> queue = new LinkedList<>(); queue.add(node); ProcessNode result = null; int count = 0; while (!queue.isEmpty()) { ProcessNode current = queue.poll(); count++; // 每个节点有相等的概率被选中 if (random.nextDouble() < 1.0 / count) { result = current; } if (current.left != null) queue.add(current.left); if (current.right != null) queue.add(current.right); } return result != null ? result : node; } @Override public Dimension getPreferredSize() { return new Dimension(1000, 800); } } // 主界面 public class ProcessBinaryTreeVisualization extends JFrame { private BinaryTreePanel treePanel; private JButton addProcessButton; private JButton addRandomButton; private JButton deleteRandomNodeButton; private JButton deleteSpecificNodeButton; private JButton operateButton; private JButton autoOperateButton; private JButton clearButton; private Timer autoTimer; public ProcessBinaryTreeVisualization() { setTitle("进程二叉树可视化与PV操作模拟 - 改进调度算法 (P0不参与队列)"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLayout(new BorderLayout()); // 创建树面板 treePanel = new BinaryTreePanel(); add(treePanel, BorderLayout.CENTER); // 创建控制面板 JPanel controlPanel = createControlPanel(); add(controlPanel, BorderLayout.SOUTH); // 创建信息面板 JPanel infoPanel = createInfoPanel(); add(infoPanel, BorderLayout.NORTH); pack(); setLocationRelativeTo(null); setSize(1000, 800); } private JPanel createControlPanel() { JPanel controlPanel = new JPanel(new FlowLayout()); // 使用支持中文的字体设置按钮 Font buttonFont = createChineseFont().deriveFont(Font.PLAIN, 14); addProcessButton = new JButton("添加单个进程"); addRandomButton = new JButton("随机生成5个进程"); deleteRandomNodeButton = new JButton("删除随机节点"); deleteSpecificNodeButton = new JButton("删除指定节点"); operateButton = new JButton("执行PV操作"); autoOperateButton = new JButton("开始自动操作"); clearButton = new JButton("清空所有节点"); // 设置按钮字体 addProcessButton.setFont(buttonFont); addRandomButton.setFont(buttonFont); deleteRandomNodeButton.setFont(buttonFont); deleteSpecificNodeButton.setFont(buttonFont); operateButton.setFont(buttonFont); autoOperateButton.setFont(buttonFont); clearButton.setFont(buttonFont); controlPanel.add(addProcessButton); controlPanel.add(addRandomButton); controlPanel.add(deleteRandomNodeButton); controlPanel.add(deleteSpecificNodeButton); controlPanel.add(operateButton); controlPanel.add(autoOperateButton); controlPanel.add(clearButton); // 添加事件监听器 addProcessButton.addActionListener(e -> { // 进程名称与ID对应,例如ID=0 -> P0, ID=1 -> P1 treePanel.insertNode(treePanel.processId, "P" + treePanel.processId); treePanel.processId++; // 插入后再递增 }); addRandomButton.addActionListener(e -> treePanel.generateRandomNodes(5)); deleteRandomNodeButton.addActionListener(e -> treePanel.deleteRandomNode()); deleteSpecificNodeButton.addActionListener(e -> deleteSpecificNode()); operateButton.addActionListener(e -> treePanel.performRandomOperation()); autoOperateButton.addActionListener(e -> toggleAutoOperation()); clearButton.addActionListener(e -> treePanel.clearAllNodes()); return controlPanel; } // 删除指定节点 private void deleteSpecificNode() { if (treePanel.root == null) { JOptionPane.showMessageDialog(this, "树为空,无法删除节点"); return; } // 获取所有可用的节点ID List<Integer> availableIds = treePanel.getAllNodeIds(); if (availableIds.isEmpty()) { JOptionPane.showMessageDialog(this, "没有可删除的节点"); return; } // 创建选择对话框 String[] options = new String[availableIds.size()]; for (int i = 0; i < availableIds.size(); i++) { options[i] = "P" + availableIds.get(i) + " (ID: " + availableIds.get(i) + ")"; } String selected = (String) JOptionPane.showInputDialog( this, "选择要删除的节点:", "删除指定节点", JOptionPane.QUESTION_MESSAGE, null, options, options[0] ); if (selected != null) { // 从选择中提取ID int id = Integer.parseInt(selected.substring(1, selected.indexOf(" "))); treePanel.deleteNodeAndChildren(id); } } private JPanel createInfoPanel() { JPanel infoPanel = new JPanel(); infoPanel.setBackground(new Color(240, 240, 240)); infoPanel.setBorder(BorderFactory.createTitledBorder("状态说明")); // 使用支持中文的字体 Font infoFont = createChineseFont().deriveFont(Font.PLAIN, 14); JLabel infoLabel = new JLabel( "<html>" + "● <font color='blue'>蓝色</font>: 就绪状态(READY) | " + "● <font color='green'>绿色</font>: 运行状态(RUNNING) | " + "● <font color='red'>红色</font>: 阻塞状态(BLOCKED) | " + "节点显示: 进程名(状态)资源数 | " + "<b>P0节点特殊规则</b>: 不消耗资源、不参与队列、不运行 | " + "初始资源: 3个,CPU: 1个 | " + "每个进程(P1开始)创建需要1个资源 | " + "<b>FCFS调度</b>: 就绪队列队首→运行队列 | " + "<b>进程流转</b>: 运行完成→就绪队列队尾 | " + "<b>资源分配</b>: 运行进程释放资源→阻塞队列队首→就绪队列队尾 | " + "就绪态不能直接转入阻塞态" + "</html>" ); infoLabel.setFont(infoFont); infoPanel.add(infoLabel); return infoPanel; } // 创建支持中文的字体 private Font createChineseFont() { String[] fontNames = { "Microsoft YaHei", "SimHei", "SimSun", "KaiTi", "Arial Unicode MS", "Dialog" }; for (String fontName : fontNames) { Font font = new Font(fontName, Font.PLAIN, 12); if (font.canDisplay('中')) { return font; } } return new Font("Dialog", Font.PLAIN, 12); } private void toggleAutoOperation() { if (autoTimer == null) { autoTimer = new Timer(1500, e -> treePanel.performRandomOperation()); autoTimer.start(); autoOperateButton.setText("停止自动操作"); addProcessButton.setEnabled(false); addRandomButton.setEnabled(false); deleteRandomNodeButton.setEnabled(false); deleteSpecificNodeButton.setEnabled(false); operateButton.setEnabled(false); } else { autoTimer.stop(); autoTimer = null; autoOperateButton.setText("开始自动操作"); addProcessButton.setEnabled(true); addRandomButton.setEnabled(true); deleteRandomNodeButton.setEnabled(true); deleteSpecificNodeButton.setEnabled(true); operateButton.setEnabled(true); } } public static void main(String[] args) { SwingUtilities.invokeLater(() -> { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (Exception e) { e.printStackTrace(); } new ProcessBinaryTreeVisualization().setVisible(true); }); } }修改代码,第一:三个队列关系,就绪队列必须等待进入运行队列,运行队列进入阻塞(进入阻塞时,必须让资源数加一)或者就绪队列(阻塞队列不变,就绪队列队首进入运行态),以此类推。第二:修改资源数为五个,CPU个数为2
最新发布
11-26
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值