2020-12-11

粗略模拟操作系统优先级调度,时间片调度和内存管理

所用语言:java
jdk version:jdk13.0.1
图形化工具:javafx
IDE:Intellij IDEA 2020.3
数据库:mysql数据库
数据库可视化工具:Navicat

一、实验目的
实验一:多道系统中,当就绪进程数大于处理机数时,须按照某种策略决定哪些进程优先占用处理机。本实验模拟实现处理机调度,加深了解处理机调度的工作过程。
实验二:帮助了解在不同的存储管理方式下,应怎样实现主存空间的分配和回收。
二、实验内容
实验一:选择一个调度算法,实现处理机调度。
1)设计一个按优先权调度算法实现处理机调度的程序;
2)设计按时间片轮转实现处理机调度的程序。
实验二:主存储器空间的分配和回收:在可变分区管理方式下,采用最先适应算法实现主存空间的分配和回收。
三、实验方法
实验一:
1)构建进程PCB,PCB内容包括:
进程名/PID;
要求运行时间(单位时间);
优先权;
状态:
PCB指针;
2)设置后备队列和挂起队列,设计作业调度算法、进程调度算法,以及挂起、解挂功能;
3)采用图形界面,动态展示调度过程中各进程及队列变化。
实验二:
1)自行假设主存空间大小,预设操作系统所占大小并构造未分分区表;
表目内容:起址、长度、状态(未分/空表目)
2)结合实验一,PCB增加为:
{PID,要求运行时间,优先权,状态,所需主存大小,主存起始位置,PCB指针}
3)采用最先适应算法分配主存空间;
4)进程完成后,回收主存,并与相邻空闲分区合并。
四、实验步骤
1)构建PCB:PCB包含实验要求的所有内容,同时选取数据库表单作为存储PCB的数据结构
2)数据库中创建reserve表用来存储后备队列,后备队列采用FIFO的算法分配;
创建PCB表存储进程的PCB,设置PCB数量最多为6;
创建Available_Memory表即未分分区表。
3)项目架构:项目分为四层:
①domain层,用来将数据库读取的记录封装成一个对象
②persistence层,该层包括连接数据库并封装数据库的sql语句,完成项目与数据库的交互
③service层,该层为业务逻辑层,主要通过调用persistence层里的方法,完成高级调度、低级调度以及程序挂起等的逻辑封装
④windows层,该层为视图层,将业务逻辑转换成图形化界面,便于理解与操作以及动态展示
4)分层完成代码的编写
5)项目后期测试
五、实验代码

实验代码层次如下:

Available_Memory.java
package org.csu.schedule.domain;
//该类用于封装未分分区表的记录
public class Available_Memory {
    private int memory_start_address;//未分内存起址
    private int memory_length;//未分内存长度
    //无参构造方法
    public Available_Memory() {
    }
    //有参构造方法
    public Available_Memory(int memory_start_address, int memory_length) {
        this.memory_start_address = memory_start_address;
        this.memory_length = memory_length;
    }

    //以下为getter和setter方法

    public int getMemory_start_address() {
        return memory_start_address;
    }

    public void setMemory_start_address(int memory_start_address) {
        this.memory_start_address = memory_start_address;
    }

    public int getMemory_length() {
        return memory_length;
    }

    public void setMemory_length(int memory_length) {
        this.memory_length = memory_length;
    }
}
PCB.java
package org.csu.schedule.domain;
//该类用于封装pcb表的记录
public class PCB {
    private String PID;//进程PID
    private int time;//进程运行所需总时间
    private int rank;//进程优先级
    private String statement;//进程状态
    private int main_memory_start_address;//进程内存起址
    private int main_memory_length;//进程所占内存长度
    //构造函数
    public PCB(String PID, int time, int rank, String statement, int main_memory_start_address, int main_memory_length) {
        this.PID = PID;
        this.time = time;
        this.rank = rank;
        this.statement = statement;
        this.main_memory_start_address = main_memory_start_address;
        this.main_memory_length = main_memory_length;
    }

    //以下为getter和setter函数

    public String getPID() {
        return PID;
    }

    public void setPID(String PID) {
        this.PID = PID;
    }

    public int getTime() {
        return time;
    }

    public void setTime(int time) {
        this.time = time;
    }

    public int getRank() {
        return rank;
    }

    public void setRank(int rank) {
        this.rank = rank;
    }

    public String getStatement() {
        return statement;
    }

    public void setStatement(String statement) {
        this.statement = statement;
    }

    public int getMain_memory_start_address() {
        return main_memory_start_address;
    }

    public void setMain_memory_start_address(int main_memory_start_address) {
        this.main_memory_start_address = main_memory_start_address;
    }

    public int getMain_memory_length() {
        return main_memory_length;
    }

    public void setMain_memory_length(int main_memory_length) {
        this.main_memory_length = main_memory_length;
    }


}
Reserve.java
package org.csu.schedule.domain;

public class Reserve {
    private int id;//逻辑主键
    private String PID;//作业名
    private int time;//作业运行时间,未被调度时为空
    private int Rank;//作业优先级
    private String statement;//作业状态,未调度时为空
    private int main_memory_start_address;//空
    private int main_memory_length;//空
    //无参构造方法
    public Reserve() {
    }
    //有参构造方法
    public Reserve(int id, String PID, int time, int rank, String statement, int main_memory_start_address, int main_memory_length) {
        this.id = id;
        this.PID = PID;
        this.time = time;
        Rank = rank;
        this.statement = statement;
        this.main_memory_start_address = main_memory_start_address;
        this.main_memory_length = main_memory_length;
    }

    //以下为getter和setter方法

    public void setId(int id) {
        this.id = id;
    }

    public int getId() {
        return id;
    }

    public String getPID() {
        return PID;
    }

    public void setPID(String PID) {
        this.PID = PID;
    }

    public int getRank() {
        return Rank;
    }

    public void setRank(int rank) {
        Rank = rank;
    }

    public int getTime() {
        return time;
    }

    public void setTime(int time) {
        this.time = time;
    }

    public String getStatement() {
        return statement;
    }

    public void setStatement(String statement) {
        this.statement = statement;
    }

    public int getMain_memory_start_address() {
        return main_memory_start_address;
    }

    public void setMain_memory_start_address(int main_memory_start_address) {
        this.main_memory_start_address = main_memory_start_address;
    }

    public int getMain_memory_length() {
        return main_memory_length;
    }

    public void setMain_memory_length(int main_memory_length) {
        this.main_memory_length = main_memory_length;
    }

}
Available_MemoryDAO
package org.csu.schedule.persistence;

import org.csu.schedule.domain.Available_Memory;

import java.util.List;

public interface Available_MemoryDAO {
     //创建Available_Memory表,每次模拟时创建,模拟结束时删除,防止上次运行结果影响下一次
     String CreateTable();
     //添加未分分区
     int add(int memory_start_address,int memory_length);
     //删除未分分区
     int delete(int memory_start_address);
     //更新未分分区
     int update(int old_memory_start_address,int memory_length,int new_memory_start_address);
     //获取所有孔的和,用于紧缩
     int get_total_memory();
     //查找是否有合适的孔
     Available_Memory select(int memory_length);
     //读取未分分区表
     List<Available_Memory> select_By_Order();
     //删除Available_Memory表,与CreateTable对应
     String DropTable();
}
Available_MemoryDAOImpl
package org.csu.schedule.persistence.Impl;

import org.csu.schedule.domain.Available_Memory;
import org.csu.schedule.domain.PCB;
import org.csu.schedule.persistence.Available_MemoryDAO;
import org.csu.schedule.persistence.DBUtils;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class Available_MemoryDAOImpl implements Available_MemoryDAO {
    @Override
    public String CreateTable() {
        String result="1";
        try{
            String sql ="CREATE TABLE Available_Memory(" +
                    "memory_start_address int not null ," +
                    "memory_length int not null);";
            Connection conn = null;
            Statement ps = null;
            conn = DBUtils.getConnection();
            ps = conn.createStatement();
            if(ps.executeUpdate(sql)==0){
                result ="创建未分分区表成功";
            }
            else result = "创建未分分区表失败";
            DBUtils.close(null,ps,conn);
        }catch (SQLException e){
            e.printStackTrace();
            result ="创建未分分区表失败";
        }
        return result;
    }

    @Override
    public int add(int memory_start_address, int memory_length) {
        Connection conn = null;
        PreparedStatement ps = null;

        conn = DBUtils.getConnection();

        String sql = "INSERT INTO Available_Memory VALUES(?,?)";
        try {
            ps = conn.prepareStatement(sql);
            ps.setInt(1, memory_start_address);
            ps.setInt(2, memory_length);
            return ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DBUtils.close(null,ps,conn);
        }
        return 0;
    }

    @Override
    public int delete(int memory_start_address) {
        Connection conn = null;
        PreparedStatement ps = null;

        conn = DBUtils.getConnection();

        String sql = "DELETE FROM Available_Memory WHERE memory_start_address = ?";
        try {
            ps = conn.prepareStatement(sql);
            ps.setInt(1, memory_start_address);
            return ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DBUtils.close(null,ps,conn);
        }
        return 0;
    }

    @Override
    public int update(int old_memory_start_address, int memory_length,int new_memory_start_address) {
        Connection conn =null;//连接对象
        PreparedStatement ps=null;//sql语句的预编译对象

        conn = DBUtils.getConnection();

        try {
            //4、创建PreparedStatement对象
            String sql = "UPDATE Available_Memory SET memory_start_address=?,memory_length=? WHERE memory_start_address=?";
            ps = conn.prepareStatement(sql);
            ps.setInt(1,new_memory_start_address);
            ps.setInt(2,memory_length);
            ps.setInt(3,old_memory_start_address);
            //5、执行
            return ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //关闭资源
            DBUtils.close(null, ps, conn);
        }
        return 0;
    }

    @Override
    public int get_total_memory() {
        Connection conn = DBUtils.getConnection();
        PreparedStatement ps = null;
        ResultSet rs = null;
        int count = 0;
        String countSQL = "select sum(memory_length) from Available_Memory";
        try {
            ps = conn.prepareStatement(countSQL);
            rs = ps.executeQuery();
            if (rs.next()) {
                count = rs.getInt(1);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DBUtils.close(rs,ps,conn);
        }
        return count;
    }

    @Override
    public Available_Memory select(int memory_length) {
        Connection conn =null;//连接对象
        PreparedStatement ps=null;//sql语句的预编译对象
        Available_Memory available_memory;
        ResultSet rs= null;
        conn = DBUtils.getConnection();

        try {
            //4、创建PreparedStatement对象
            String sql = "SELECT * FROM Available_Memory WHERE memory_length>=?";
            ps = conn.prepareStatement(sql);
            ps.setInt(1,memory_length);
            //5、执行
            rs=ps.executeQuery();
            //6.解析结果集
            if (rs.next()) {
                available_memory=new Available_Memory(rs.getInt(1),rs.getInt(2));
                return available_memory;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //关闭资源
            DBUtils.close(rs , ps, conn);
        }
        return null;
    }

    @Override
    public List<Available_Memory> select_By_Order() {
        Connection conn =null;//连接对象
        PreparedStatement ps=null;//sql语句的预编译对象
        List<Available_Memory> list = new ArrayList<>();
        ResultSet rs= null;
        conn = DBUtils.getConnection();

        try {
            //4、创建PreparedStatement对象
            String sql = "SELECT * FROM Available_Memory ORDER BY memory_start_address";
            ps = conn.prepareStatement(sql);
            //5、执行
            rs=ps.executeQuery();
            //6.解析结果集
            while(rs.next()) {
                Available_Memory available_memory=new Available_Memory(rs.getInt(1),rs.getInt(2));
                list.add(available_memory);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //关闭资源
            DBUtils.close(rs , ps, conn);
        }
        return list;
    }

    @Override
    public String DropTable() {
        String result="";
        try{
            String sql ="DROP TABLE Available_Memory";
            Connection conn = null;
            Statement ps = null;
            conn = DBUtils.getConnection();
            ps = conn.createStatement();
            if(ps.executeUpdate(sql)==0){
                result="删除未分分区表成功";
            }
            else result="删除未分分区表失败";
            DBUtils.close(null,ps,conn);
        }catch (SQLException e){
            e.printStackTrace();
            result="删除未分分区表失败";
        }
        return result;
    }
}
PCBDAO
package org.csu.schedule.persistence;

import org.csu.schedule.domain.PCB;

import java.util.List;

public interface PCBDAO {
     //创建pcb表,每次模拟时创建,模拟结束时删除,防止上次运行结果影响下一次
     String createtable();
     //添加记录
     int add(String PID,int time,int rank,String statement,int main_memory_start_address,int main_memory_length);
     //删除记录
     int delete(String PID);
     //更新记录的time,rank,statement属性,在一次运行结束时调用
     int update(String PID,int time,int rank,String statement);
     //更新记录的statement属性,挂起等使用
     int update(String PID,String statement);
     //更新内存状态,紧缩等使用
     int update(int old_memory_start_address,int new_memory_start_address);
     //根据statement查询记录
     List<PCB> select(String statement,int index, int count);
     //查询所有记录
     List<PCB> select(int index,int count);
     //根据statement查询记录并按优先级排序
     List<PCB> selectBy_rank(String statement);
     //查询所有记录并按内存地址排序
     List<PCB> selectBy_start_address();
     //根据PID查询进程
     PCB selectBy_PID(String PID);
     //查询记录数,即进程数
     int count();
     //删除pcb表,与createtable对应
     String droptable();
}
PCBDAOImpl
package org.csu.schedule.persistence.Impl;

import org.csu.schedule.domain.PCB;
import org.csu.schedule.persistence.DBUtils;
import org.csu.schedule.persistence.PCBDAO;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class PCBDAOImpl implements PCBDAO {

    public PCBDAOImpl() {
    }

    @Override
    public String createtable() {
        String result="1";
        try{
            String sql ="CREATE TABLE pcb(" +
                    "id int primary key auto_increment ," +
                    "PID varchar(30) not null," +
                    "time int not null," +
                    "rank int not null," +
                    "statement varchar(30) not null," +
                    "main_memory_start_address int not null," +
                    "main_memory_length int not null );";
            Connection conn = null;
            Statement ps = null;
            conn = DBUtils.getConnection();
            ps = conn.createStatement();
            if(ps.executeUpdate(sql)==0){
                result ="创建pcb表成功";
            }
            else result = "创建pcb表失败";
            DBUtils.close(null,ps,conn);
        }catch (SQLException e){
            e.printStackTrace();
            result ="创建pcb表失败";
        }
        return result;
    }

    @Override
    public int add(String PID, int time, int rank, String statement,int main_memory_start_address,int main_memory_length) {
        Connection conn = null;
        PreparedStatement ps = null;

        conn = DBUtils.getConnection();

        String sql = "INSERT INTO pcb VALUES(null,?,?,?,?,?,?)";
        try {
            ps = conn.prepareStatement(sql);
            ps.setString(1, PID);
            ps.setInt(2, time);
            ps.setInt(3,rank);
            ps.setString(4,statement);
            ps.setInt(5,main_memory_start_address);
            ps.setInt(6,main_memory_length);
            return ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        finally
        {
            DBUtils.close(null,ps,conn);
        }
        return 0;
    }

    @Override
    public int delete(String PID) {
        Connection conn = null;
        PreparedStatement ps = null;

        conn = DBUtils.getConnection();

        String sql = "DELETE FROM pcb WHERE PID = ?";
        try {
            ps = conn.prepareStatement(sql);
            ps.setString(1, PID);
            return ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        finally
        {
            DBUtils.close(null,ps,conn);
        }
        return 0;
    }

    @Override
    public int update(String PID, int time, int rank, String statement) {
        Connection conn =null;//连接对象
        PreparedStatement ps=null;//sql语句的预编译对象

        conn = DBUtils.getConnection();

        try {
            //4、创建PreparedStatement对象
            String sql = "UPDATE pcb SET time=?,rank=?,statement=? WHERE PID=?";
            ps = conn.prepareStatement(sql);
            ps.setInt(1,time);
            ps.setInt(2, rank);
            ps.setString(3,statement);
            ps.setString(4, PID);
            //5、执行
            return ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //关闭资源
            DBUtils.close(null, ps, conn);
        }
        return 0;
    }

    @Override
    public int update(String PID, String statement) {
        Connection conn =null;//连接对象
        PreparedStatement ps=null;//sql语句的预编译对象

        conn = DBUtils.getConnection();

        try {
            //4、创建PreparedStatement对象
            String sql = "UPDATE pcb SET statement=? WHERE PID=?";
            ps = conn.prepareStatement(sql);
            ps.setString(1,statement);
            ps.setString(2, PID);
            //5、执行
            return ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //关闭资源
            DBUtils.close(null, ps, conn);
        }
        return 0;
    }

    @Override
    public int update(int old_memory_start_address,int new_memory_start_address) {
        Connection conn =null;//连接对象
        PreparedStatement ps=null;//sql语句的预编译对象

        conn = DBUtils.getConnection();

        try {
            //4、创建PreparedStatement对象
            String sql = "UPDATE pcb SET main_memory_start_address=? WHERE main_memory_start_address=?";
            ps = conn.prepareStatement(sql);
            ps.setInt(1,new_memory_start_address);
            ps.setInt(2,old_memory_start_address);
            //5、执行
            return ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //关闭资源
            DBUtils.close(null, ps, conn);
        }
        return 0;
    }

    @Override
    public List<PCB> select(String statement,int index, int count) {
        Connection conn =null;//连接对象
        PreparedStatement ps=null;//sql语句的预编译对象
        List<PCB> list = new ArrayList<>();
        ResultSet rs= null;
        conn = DBUtils.getConnection();

        try {
            //4、创建PreparedStatement对象
            String sql = "SELECT * FROM pcb WHERE statement=? LIMIT ?,?";
            ps = conn.prepareStatement(sql);
            ps.setString(1,statement);
            ps.setInt(2, index);
            ps.setInt(3, count);
            //5、执行
            rs=ps.executeQuery();
            //6.解析结果集
            while(rs.next()) {
                PCB pcb=new PCB(rs.getString(2),rs.getInt(3),rs.getInt(4),rs.getString(5),rs.getInt(6),rs.getInt(7));
                list.add(pcb);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //关闭资源
            DBUtils.close(rs , ps, conn);
        }
        return list;
    }

    @Override
    public List<PCB> select(int index, int count) {
        Connection conn =null;//连接对象
        PreparedStatement ps=null;//sql语句的预编译对象
        List<PCB> list = new ArrayList<>();
        ResultSet rs= null;
        conn = DBUtils.getConnection();

        try {
            //4、创建PreparedStatement对象
            String sql = "SELECT * FROM pcb LIMIT ?,?";
            ps = conn.prepareStatement(sql);
            ps.setInt(1, index);
            ps.setInt(2, count);
            //5、执行
            rs=ps.executeQuery();
            //6.解析结果集
            while(rs.next()) {
                PCB pcb=new PCB(rs.getString(2),rs.getInt(3),rs.getInt(4),rs.getString(5),rs.getInt(6),rs.getInt(7));
                list.add(pcb);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //关闭资源
            DBUtils.close(rs , ps, conn);
        }
        return list;
    }

    @Override
    public List<PCB> selectBy_rank(String statement) {
        Connection conn =null;//连接对象
        PreparedStatement ps=null;//sql语句的预编译对象
        List<PCB> list = new ArrayList<>();
        ResultSet rs= null;
        conn = DBUtils.getConnection();

        try {
            //4、创建PreparedStatement对象
            String sql = "SELECT * FROM pcb WHERE statement=? ORDER BY rank DESC ";
            ps = conn.prepareStatement(sql);
            ps.setString(1,statement);
            //5、执行
            rs=ps.executeQuery();
            //6.解析结果集
            while(rs.next()) {
                PCB pcb=new PCB(rs.getString(2),rs.getInt(3),rs.getInt(4),rs.getString(5),rs.getInt(6),rs.getInt(7));
                list.add(pcb);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //关闭资源
            DBUtils.close(rs , ps, conn);
        }
        return list;
    }

    @Override
    public List<PCB> selectBy_start_address() {
        Connection conn =null;//连接对象
        PreparedStatement ps=null;//sql语句的预编译对象
        List<PCB> list = new ArrayList<>();
        ResultSet rs= null;
        conn = DBUtils.getConnection();

        try {
            //4、创建PreparedStatement对象
            String sql = "SELECT * FROM pcb ORDER BY main_memory_start_address";
            ps = conn.prepareStatement(sql);
            //5、执行
            rs=ps.executeQuery();
            //6.解析结果集
            while(rs.next()) {
                PCB pcb=new PCB(rs.getString(2),rs.getInt(3),rs.getInt(4),rs.getString(5),rs.getInt(6),rs.getInt(7));
                list.add(pcb);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //关闭资源
            DBUtils.close(rs , ps, conn);
        }
        return list;
    }

    @Override
    public PCB selectBy_PID(String PID) {
        Connection conn =null;//连接对象
        PreparedStatement ps=null;//sql语句的预编译对象
        PCB pcb=null;
        ResultSet rs= null;
        conn = DBUtils.getConnection();

        try {
            //4、创建PreparedStatement对象
            String sql = "SELECT * FROM pcb WHERE PID=?";
            ps = conn.prepareStatement(sql);
            ps.setString(1,PID);
            //5、执行
            rs=ps.executeQuery();
            //6.解析结果集
            if (rs.next()) {
                pcb=new PCB(rs.getString(2),rs.getInt(3),rs.getInt(4),rs.getString(5),rs.getInt(6),rs.getInt(7));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //关闭资源
            DBUtils.close(rs , ps, conn);
        }
        return pcb;
    }

    @Override
    public int count() {
        Connection conn = DBUtils.getConnection();
        PreparedStatement ps = null;
        ResultSet rs = null;
        String countSQL = "select count(*) as result from pcb";
        int count = 0;
        try
        {
            ps = conn.prepareStatement(countSQL);
            rs = ps.executeQuery();
            if (rs.next()) {
                count = rs.getInt(1);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DBUtils.close(rs,ps,conn);
        }
        return count;
    }

    @Override
    public String droptable() {
        String result="";
        try{
            String sql ="DROP TABLE pcb";
            Connection conn = null;
            Statement ps = null;
            conn = DBUtils.getConnection();
            ps = conn.createStatement();
            if(ps.executeUpdate(sql)==0){
                result="删除pcb表成功";
            }
            else result="删除pcb表失败";
            DBUtils.close(null,ps,conn);
        }catch (SQLException e){
            e.printStackTrace();
            result="删除pcb表失败";
        }
        return result;
    }

}
ReserveDAO
package org.csu.schedule.persistence;

import org.csu.schedule.domain.Reserve;

import java.util.List;

public interface ReserveDAO {
    //添加作业
    int add(String PID, int rank, int main_memory_length);
    //删除作业
    int delete(String PID);
    //更新作业
    int update(String PID, int rank);
    //查询限定条数的作业
    List<Reserve> select(int index, int count);
    //返回下一个作业
    Reserve next(int i);
}
ReserveDAOImpl
package org.csu.schedule.persistence.Impl;

import org.csu.schedule.domain.Reserve;
import org.csu.schedule.persistence.DBUtils;
import org.csu.schedule.persistence.ReserveDAO;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class ReserveDAOImpl implements ReserveDAO {
    @Override
    public int add(String PID,int rank,int main_memory_length) {
        Connection conn;
        PreparedStatement ps = null;

        conn = DBUtils.getConnection();

        String sql = "INSERT INTO reserve VALUES(null,?,null,?,null,null,?)";
        try {
            ps = conn.prepareStatement(sql);
            ps.setString(1, PID);
            ps.setInt(2, rank);
            ps.setInt(3,main_memory_length);
            return ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        finally
        {
            DBUtils.close(null,ps,conn);
        }
        return 0;
    }

    @Override
    public int delete(String PID) {
        Connection conn;
        PreparedStatement ps = null;

        conn = DBUtils.getConnection();

        String sql = "DELETE FROM reserve WHERE PID = ?";
        try {
            ps = conn.prepareStatement(sql);
            ps.setString(1, PID);
            return ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        finally
        {
            DBUtils.close(null,ps,conn);
        }
        return 0;
    }

    @Override
    public int update(String PID,int rank) {
        Connection conn =null;//连接对象
        PreparedStatement ps=null;//sql语句的预编译对象

        conn = DBUtils.getConnection();

        try {
            //4、创建PreparedStatement对象
            String sql = "UPDATE reserve SET rank=? WHERE PID=?";
            ps = conn.prepareStatement(sql);
            ps.setInt(1, rank);
            ps.setString(2, PID);
            //5、执行
            return ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //关闭资源
            DBUtils.close(null, ps, conn);
        }
        return 0;
    }

    @Override
    public List<Reserve> select(int index,int count) {
        Connection conn =null;//连接对象
        PreparedStatement ps=null;//sql语句的预编译对象
        List<Reserve> list = new ArrayList<>();
        ResultSet rs= null;
        conn = DBUtils.getConnection();

        try {
            //4、创建PreparedStatement对象
            String sql = "SELECT * FROM reserve LIMIT ?,?";
            ps = conn.prepareStatement(sql);
            ps.setInt(1, index);
            ps.setInt(2, count);
            //5、执行
            rs=ps.executeQuery();
            //6.解析结果集
            while(rs.next()) {
                Reserve reserve=new Reserve(rs.getInt(1),rs.getString(2),rs.getInt(3),rs.getInt(4),rs.getString(5),rs.getInt(6),rs.getInt(7));
                list.add(reserve);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //关闭资源
            DBUtils.close(rs , ps, conn);
        }
        return list;
    }

    @Override
    public Reserve next(int i) {
        List<Reserve> list = select(0,10000);
        if (i<list.size()){
            if(list.get(i)!=null) {
                return list.get(i);
            }
        }
        return null;
    }

}
DBUtils
package org.csu.schedule.persistence;

import java.sql.*;
//数据库连接
public class DBUtils {
    public static Connection getConnection() {

        try {
            //1.加载驱动
            Class.forName("com.mysql.jdbc.Driver");

            //2.定义url
            String url ="jdbc:mysql://localhost:3306/schedule?useUnicode=true&autoReconnect=true";
            String user = "root";
            String pwd = "123456";

            //3.创建连接
            return DriverManager.getConnection(url, user, pwd);
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void close(ResultSet rs, Statement stmt, Connection conn) {

        if(rs!=null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(stmt!=null) {
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(conn!=null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}
Function.java
package org.csu.schedule.service;

import org.csu.schedule.domain.Available_Memory;
import org.csu.schedule.domain.PCB;
import org.csu.schedule.domain.Reserve;
import org.csu.schedule.persistence.Available_MemoryDAO;
import org.csu.schedule.persistence.Impl.Available_MemoryDAOImpl;
import org.csu.schedule.persistence.Impl.PCBDAOImpl;
import org.csu.schedule.persistence.Impl.ReserveDAOImpl;

import java.util.List;
//业务逻辑层
public class Function {
    //使用persistence层
    private final PCBDAOImpl PDI;
    private final ReserveDAOImpl RDI;
    private final Available_MemoryDAO AMDI;
    //无参构造函数
    public Function() {
        PDI = new PCBDAOImpl();
        RDI = new ReserveDAOImpl();
        AMDI = new Available_MemoryDAOImpl();
    }
    //高级调度
    public String highschedule(){
        int assignment=0;
        Reserve nextR = RDI.next(assignment);
        Available_Memory available_memory;
        //遍历后备队列,查找合适的作业进内存
        while(nextR!=null){
            //查找是否有合适的孔
            available_memory = AMDI.select(nextR.getMain_memory_length());
            //若没有合适的孔
            if(available_memory==null) {
                //若紧缩后内存充足,紧缩
                if(AMDI.get_total_memory()>=nextR.getMain_memory_length()){
                    //紧缩并在下一次循环调度,当前作业进行下一次判断
                    int address_after_regulate=regulate();
                    String step1 = AMDI.DropTable();
                    String step2 = AMDI.CreateTable();
                    if (step1.equals("删除未分分区表成功")&&step2.equals("创建未分分区表成功")){
                        System.out.println("内存整理完成");
                    }
                    AMDI.add(address_after_regulate,100-address_after_regulate);
                }
                //若紧缩后内存不足
                else {
                    //查找下一内存
                    assignment++;
                    nextR = RDI.next(assignment);
                }
            }
            //若有大小合适的孔
            else{
                //分配内存
                PDI.add(nextR.getPID(),(int)(1+Math.random()*20),nextR.getRank(),"ready",available_memory.getMemory_start_address(),nextR.getMain_memory_length());
                RDI.delete(nextR.getPID());
                int new_memory_length= available_memory.getMemory_length()-nextR.getMain_memory_length();
                if(new_memory_length==0){
                    AMDI.delete(available_memory.getMemory_start_address());
                }else {
                    AMDI.update(available_memory.getMemory_start_address(),new_memory_length,available_memory.getMemory_start_address()+nextR.getMain_memory_length());
                }
                //返回作业名
                return nextR.getPID();
            }
        }
        //若所有作业都不满足调度条件
        return "后备队列无合适作业";
    }
    //按优先级的低级调度算法,返回被调度的进程的进程名,若没有进程被调度则为“”
    public String lowschedule_By_Priority(){
        String PID="";
        List<PCB> list;
        //判断当前是否有进程正在运行
        if(PDI.select("running",0,1).size()==0){
            //若无进程,将最高优先级的进程送入CPU
            list = PDI.selectBy_rank("ready");
            if(!list.isEmpty()){
                PID=list.get(0).getPID();
                PDI.update(PID,"running");
            }
        }
        //返回进程名
        return PID;
    }
    //按时间片的低级调度,返回被调度的进程的进程名,若没有进程被调度则为“”
    public String lowschedule_By_TimeSlice(int i){
        String PID="";
        List<PCB> list;
        int k=i;
        //判断是否有进程正在运行
        if(PDI.select("running",0,1).size()==0){
            //按顺序查找进程
            list = PDI.select(0,6);
            //挂起的进程不会被调度
            while(list.get(k).getStatement().equals("hangup")){
                k=(k+1)%6;
            }
            PID=list.get(k).getPID();
            PDI.update(PID,"running");
        }
        //返回进程名
        return PID;
    }
    //进程一次CPU运行结束,返回运行结束的进程的进程名,若没有进程则为“”
    public String runover(){
        //获取当前正在运行的进程
        List<PCB> list = PDI.select("running",0,1);
        if(list.size()!=0){
            PCB a=list.get(0);
            //若进程以全部运行结束
            if(a.getTime()==1){
                //回收内存
                AMDI.add(a.getMain_memory_start_address(),a.getMain_memory_length());
                //合并内存
                combine(a.getMain_memory_start_address(),a.getMain_memory_length());
                PDI.delete(a.getPID());
            }
            //若没结束,则重新进入就绪队列
            else {
                PDI.update(a.getPID(),a.getTime()-1,a.getRank()-1==0?1:(a.getRank()-1),"ready");
            }
            //返回进程名
            return a.getPID();
        }
        return "";
    }
    //紧缩
    private int regulate(){
        int new_start_address=20;
        List<PCB> list;
        list=PDI.selectBy_start_address();
        for (PCB pcb : list) {
            //所有内存上移
            PDI.update(pcb.getMain_memory_start_address(), new_start_address);
            //下一个内存应上移到的位置
            new_start_address += pcb.getMain_memory_length();
        }
        //返回紧缩完成后的未分分区表起址
        return new_start_address;
    }
    //内存回收时合并内存
    private void combine(int start,int length){
        boolean is_pre=false;
        int pre_address=0;
        int pre_length=0;
        List<Available_Memory> list;
        list=AMDI.select_By_Order();
        //遍历未分分区表
        for (Available_Memory available_memory : list) {
            //若满足向上合并条件
            if ((available_memory.getMemory_start_address() + available_memory.getMemory_length()) == start) {
                is_pre = true;
                pre_address = available_memory.getMemory_start_address();
                pre_length = available_memory.getMemory_length();
                AMDI.update(pre_address, pre_length + length, pre_address);
                AMDI.delete(start);
            }
            //若满足向下合并条件
            if (available_memory.getMemory_start_address() == (start + length)) {
                //若进行过向上合并
                if (is_pre) {
                    AMDI.update(pre_address, pre_length + length + available_memory.getMemory_length(), pre_address);
                }
                //若没有进行过向上合并
                else {
                    AMDI.update(start, length + available_memory.getMemory_length(), start);
                }
                AMDI.delete(start + length);
            }
            //合并完成,跳出循环
            if (available_memory.getMemory_start_address() > start + length) break;
        }
    }

}
Control_Main
package org.csu.schedule.windows;

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
import javafx.application.Platform;
import org.csu.schedule.domain.PCB;
import org.csu.schedule.domain.Reserve;
import org.csu.schedule.persistence.Available_MemoryDAO;
import org.csu.schedule.persistence.Impl.Available_MemoryDAOImpl;
import org.csu.schedule.persistence.Impl.PCBDAOImpl;
import org.csu.schedule.persistence.Impl.ReserveDAOImpl;
import org.csu.schedule.service.Function;

import javax.swing.*;
import java.awt.*;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Timer;
import java.util.*;

public class Controller_Main extends Application{

    public ToggleGroup Querygroup;
    public TextArea dailyRecord;
    public ToggleButton ready;
    public ToggleButton hangup;
    public ToggleButton running;
    public ToggleButton reserve;
    public Label user;
    public Label nameOfDR;
    public TableView Process;
    public TableColumn<Object, Object> PID;
    public TableColumn Time;
    public TableColumn Rank;
    public TableColumn Statement;
    public AnchorPane Main_pane;
    public Button button_start;
    public TableColumn main_memory_start_address;
    public TableColumn main_memory_length;

    public SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    public Button hangup_button;
    public javafx.scene.shape.Rectangle rectangle1;
    public Label label_memory;
    public Label label_PID;
    public Label label_Time;
    public Label label_rank;
    public Label label_Statement;
    public Label label_start_address;
    public Label label_memory_length;
    public Label pcb1;
    public Label pcb2;
    public Label pcb3;
    public Label pcb4;
    public Label pcb5;
    public Label pcb6;
    private int i = 0;
    private int assignment = 0;//控制作业自动添加的时间间隔
    private int which=1;//which=1表示优先级调度,which=0表示时间片轮转调度
    private int rr=0;
    private String record;
    private final PCBDAOImpl PDI = new PCBDAOImpl();
    private final Function function = new Function();
    private final ReserveDAOImpl RDI = new ReserveDAOImpl();
    private final Available_MemoryDAOImpl AMDI = new Available_MemoryDAOImpl();
    private Timer timer;
    private Label aaaa;
    private List<Label> pcbsix= new ArrayList<>();
    private List<Label> labelList= new ArrayList<>();

    @Override
    public void start(Stage primaryStage) throws Exception{
        PCBDAOImpl PDI = new PCBDAOImpl();
        Available_MemoryDAO AMDI = new Available_MemoryDAOImpl();
        //程序运行时创建pcb表和Available_Memory表
        System.out.println(PDI.createtable());
        String Create_memory_table = AMDI.CreateTable();
        if(Create_memory_table.equals("创建未分分区表成功")){
            System.out.println(Create_memory_table);
            AMDI.add(20,80);
        }
        Parent root = FXMLLoader.load(getClass().getResource("Main.fxml"));
        primaryStage.setTitle("操作系统模拟");
        primaryStage.setScene(new Scene(root, 1050, 696));
        primaryStage.show();
        //程序关闭时删除pcb表和Available_Memory表
        primaryStage.setOnCloseRequest(windowEvent -> {
            System.out.println(AMDI.DropTable());
            System.out.println(PDI.droptable());
            System.exit(0);
        });
    }

    public static void main(String[] args) {
        launch(args);
    }
    //鼠标点击选择队列时触发,更新表单
    public void ChooseQuery(){
        update();
    }
    //更新表单,根据选择的不同队列来显示相应的内容
    public void update(){
        if(Querygroup.getSelectedToggle()!=null){
            ready.setUserData("ready");
            hangup.setUserData("hangup");
            running.setUserData("running");
            reserve.setUserData("reserve");
            final ObservableList <PCB> data1 = FXCollections.observableArrayList();
            final ObservableList <Reserve> data2 = FXCollections.observableArrayList();
            PID.setCellValueFactory(new PropertyValueFactory<>("PID"));
            Time.setCellValueFactory(new PropertyValueFactory<>("Time"));
            Rank.setCellValueFactory(new PropertyValueFactory<>("Rank"));
            Statement.setCellValueFactory(new PropertyValueFactory<>("Statement"));
            main_memory_start_address.setCellValueFactory(new PropertyValueFactory<>("main_memory_start_address"));
            main_memory_length.setCellValueFactory(new PropertyValueFactory<>("main_memory_length"));
            //就绪队列
            if(Querygroup.getSelectedToggle().getUserData().equals("ready")){
                PCBDAOImpl PDI = new PCBDAOImpl();
                List <PCB> list ;
                //不同调度方法显示不同
                if(which == 1){
                    list = PDI.selectBy_rank("ready");
                } else {
                    list = PDI.select("ready",0,100);
                }
                for (PCB pcb : list) {
                    if (pcb.getStatement().equals("ready")) {
                        data1.add(pcb);
                    }
                }
                Process.setItems(data1);
            }
            //挂起队列
            else if(Querygroup.getSelectedToggle().getUserData().equals("hangup")){
                PCBDAOImpl PDI = new PCBDAOImpl();
                List<PCB> list = PDI.select("hangup",0,10);
                data1.addAll(list);
                Process.setItems(data1);
            }
            //后备队列
            else if(Querygroup.getSelectedToggle().getUserData().equals("reserve")){
                ReserveDAOImpl RDI = new ReserveDAOImpl();
                List<Reserve> list = RDI.select(0,1000);
                data2.addAll(list);
                Process.setItems(data2);
            }
            //运行队列
            else{
                PCBDAOImpl PDI = new PCBDAOImpl();
                List<PCB> list = PDI.select("running",0,10);
                data1.addAll(list);
                Process.setItems(data1);
            }
        }
    }
    //开始按钮,用以控制程序的开始
    public void on_button_start() {
        pcbsix.add(pcb1);
        pcbsix.add(pcb2);
        pcbsix.add(pcb3);
        pcbsix.add(pcb4);
        pcbsix.add(pcb5);
        pcbsix.add(pcb6);
        button_start.setVisible(false);
        //计时器开始,程序核心功能开始运行
        set_schedule_Timer();
    }
    //添加作业窗口
    public void on_button_add() throws Exception {
        Controller_Add a = new Controller_Add();
        a.showWindow();
    }
    //挂起窗口
    public void on_button_hangup() {
        //程序暂时停止
        timer.cancel();
        List<PCB> list =PDI.select(0,10);
        //根据是否有进程能够挂起弹出不同的窗口
        if(list.isEmpty()){
            JOptionPane.showMessageDialog(null,"没有进程能够满足挂起条件","挂起进程失败",JOptionPane.ERROR_MESSAGE);
        }
        //若有进程能挂起
        else {
            //挂起进程
            Object[] hang_up_able = new Object[list.size()];
            for (int i1=0;i1<list.size();i1++){
                hang_up_able[i1]=list.get(i1).getPID();
            }
            Object selected=JOptionPane.showInputDialog(null,"请选择进程挂起","挂起进程",JOptionPane.INFORMATION_MESSAGE,null,hang_up_able,hang_up_able[0]);
            PDI.update((String) selected,"hangup");
            //日志
            dailyRecord.appendText(df.format(new Date())+" "+ selected +"被挂起"+'\n');
        }
        //程序重新运行
        set_schedule_Timer();
    }
    //解挂窗口
    public void on_button_remove() {
        //程序暂时停止
        timer.cancel();
        List<PCB> list = PDI.select("hangup",0,10);
        //根据是否有进程能够解挂弹出不同的窗口
        if(list.isEmpty()){
            JOptionPane.showMessageDialog(null,"没有进程处于挂起状态","解挂进程失败",JOptionPane.ERROR_MESSAGE);
        }
        //若有进程能够解挂
        else{
            //解挂进程
            Object[] hanged_up = new Object[list.size()];
            for (int i1=0;i1<list.size();i1++){
                hanged_up[i1] = list.get(i1).getPID();
            }
            Object selected=JOptionPane.showInputDialog(null,"请选择进程解挂","解挂进程",JOptionPane.INFORMATION_MESSAGE,null,hanged_up,hanged_up[0]);
            PDI.update((String) selected,"ready");
            //日志
            dailyRecord.appendText(df.format(new Date())+" "+selected+"解除挂起\n");
        }
        //程序重新运行
        set_schedule_Timer();
    }
    //结束进程
    public void on_button_terminate() {
        //程序暂时停止
        timer.cancel();
        List<PCB> list =PDI.select(0,10);
        //根据是否有进程能够结束弹出不同的窗口
        if(list.isEmpty()){
            JOptionPane.showMessageDialog(null,"内存内没有内存","Error",JOptionPane.ERROR_MESSAGE);
        }
        //若有程序能够结束
        else {
            //结束程序,回收内存并高调
            Object[] terminate_pcb = new Object[list.size()];
            for (int i1=0;i1<list.size();i1++){
                terminate_pcb[i1]=list.get(i1).getPID();
            }
            Object selected=JOptionPane.showInputDialog(null,"请选择进程结束","结束进程",JOptionPane.INFORMATION_MESSAGE,null,terminate_pcb,terminate_pcb[0]);
            //结束程序
            PCB a = PDI.selectBy_PID((String) selected);
            PDI.delete((String) selected);
            //回收内存
            AMDI.add(a.getMain_memory_start_address(),a.getMain_memory_length());
            //高调
            function.highschedule();
            //日志
            dailyRecord.appendText(df.format(new Date())+" "+ selected +"异常结束"+'\n');
        }
        //程序重新开始
        set_schedule_Timer();
    }
    //选择不同的调度
    public void Choose_Schedule(){
        if(which == 1){
            record = function.lowschedule_By_Priority();
            if(record.length()!=0) dailyRecord.appendText(df.format(new Date())+" 进程"+record+"进入CPU运行"+'\n');
        }
        else {
            record = function.lowschedule_By_TimeSlice(rr);
            if(record.length()!=0) {
                rr=(rr+1)%6;
                dailyRecord.appendText(df.format(new Date())+" 进程"+record+"进入CPU运行"+'\n');
            }
        }
        update();
    }
    //切换为优先级调度
    public void on_button_Priority() {
        which = 1;
    }
    //切换为时间片调度
    public void on_button_timeSlice() {
        which =0;
    }
    //程序核心功能,定时器
    private void set_schedule_Timer(){
        TimerTask task1 = new TimerTask() {
            @Override
            public void run() {
                //图形化界面的实时更新
                Platform.runLater(new Runnable() {
                    @Override
                    public void run() {
                        labelList = update_picture(labelList);
                    }
                });
                //作业每4个单位时间自动添加
                assignment++;
                if(assignment==4){
                    List<Reserve> list = RDI.select(0,10000);
                    int id1=(list.get(list.size()-1).getId()+1);
                    String id = "Auto_Create"+id1;
                    RDI.add(id,(int)(1+Math.random()*10),(int)(10+Math.random()*11));
                    dailyRecord.appendText(df.format(new Date())+" 作业"+id+"被创建"+'\n');

                    update();
                    assignment=0;
                }
                //如果进程数小于6,高级调度
                if(PDI.count()<6) {
                    record = function.highschedule();
                    if(record.length()!=0) dailyRecord.appendText(df.format(new Date())+" 作业"+record+"进入就绪队列"+'\n');
                    update();
                }
                //低调
                Choose_Schedule();
                i++;
                //每两个时间单位进程CPU结束运行一次
                if(i == 2){
                    record = function.runover();
                    if(record.length()!=0)dailyRecord.appendText(df.format(new Date())+" 进程"+record+"一次运行结束"+'\n');
                    update();
                    Choose_Schedule();
                    i = 0;
                }
                Platform.runLater(() -> labelList = update_picture(labelList));
            }
        };
        timer = new Timer();
        timer.scheduleAtFixedRate(task1,3000,5000);
    }
    //鼠标触摸事件,当鼠标接触时显示详细信息
    public void show_pcb_detail1(MouseEvent mouseEvent) {
        if(!pcb1.getText().equals("null")){
            PCB nowpcb = PDI.selectBy_PID(pcb1.getText());
            label_PID.setText("PID:"+nowpcb.getPID());
            label_rank.setText("Rank:"+nowpcb.getRank());
            label_Statement.setText("Statement:"+nowpcb.getStatement());
            label_Time.setText("Time:"+nowpcb.getTime());
            label_start_address.setText("Main_memory_start_address:"+nowpcb.getMain_memory_start_address());
            label_memory_length.setText("Main_memory_length:"+nowpcb.getMain_memory_length());
            label_PID.setVisible(true);
            label_Time.setVisible(true);
            label_memory_length.setVisible(true);
            label_Statement.setVisible(true);
            label_start_address.setVisible(true);
            label_rank.setVisible(true);
        }
    }
    //鼠标触摸事件,当鼠标接触时显示详细信息
    public void show_pcb_detail2(MouseEvent mouseEvent) {
        if(!pcb2.getText().equals("null")){
            PCB nowpcb = PDI.selectBy_PID(pcb2.getText());
            label_PID.setText("PID:"+nowpcb.getPID());
            label_rank.setText("Rank:"+nowpcb.getRank());
            label_Statement.setText("Statement:"+nowpcb.getStatement());
            label_Time.setText("Time:"+nowpcb.getTime());
            label_start_address.setText("Main_memory_start_address:"+nowpcb.getMain_memory_start_address());
            label_memory_length.setText("Main_memory_length:"+nowpcb.getMain_memory_length());
            label_PID.setVisible(true);
            label_Time.setVisible(true);
            label_memory_length.setVisible(true);
            label_Statement.setVisible(true);
            label_start_address.setVisible(true);
            label_rank.setVisible(true);
        }
    }
    //鼠标触摸事件,当鼠标接触时显示详细信息
    public void show_pcb_detail3(MouseEvent mouseEvent) {
        if(!pcb3.getText().equals("null")){
            PCB nowpcb = PDI.selectBy_PID(pcb3.getText());
            label_PID.setText("PID:"+nowpcb.getPID());
            label_rank.setText("Rank:"+nowpcb.getRank());
            label_Statement.setText("Statement:"+nowpcb.getStatement());
            label_Time.setText("Time:"+nowpcb.getTime());
            label_start_address.setText("Main_memory_start_address:"+nowpcb.getMain_memory_start_address());
            label_memory_length.setText("Main_memory_length:"+nowpcb.getMain_memory_length());
            label_PID.setVisible(true);
            label_Time.setVisible(true);
            label_memory_length.setVisible(true);
            label_Statement.setVisible(true);
            label_start_address.setVisible(true);
            label_rank.setVisible(true);
        }
    }
    //鼠标触摸事件,当鼠标接触时显示详细信息
    public void show_pcb_detail4(MouseEvent mouseEvent) {
        if(!pcb4.getText().equals("null")){
            PCB nowpcb = PDI.selectBy_PID(pcb4.getText());
            label_PID.setText("PID:"+nowpcb.getPID());
            label_rank.setText("Rank:"+nowpcb.getRank());
            label_Statement.setText("Statement:"+nowpcb.getStatement());
            label_Time.setText("Time:"+nowpcb.getTime());
            label_start_address.setText("Main_memory_start_address:"+nowpcb.getMain_memory_start_address());
            label_memory_length.setText("Main_memory_length:"+nowpcb.getMain_memory_length());
            label_PID.setVisible(true);
            label_Time.setVisible(true);
            label_memory_length.setVisible(true);
            label_Statement.setVisible(true);
            label_start_address.setVisible(true);
            label_rank.setVisible(true);
        }
    }
    //鼠标触摸事件,当鼠标接触时显示详细信息
    public void show_pcb_detail5(MouseEvent mouseEvent) {
        if(!pcb5.getText().equals("null")){
            PCB nowpcb = PDI.selectBy_PID(pcb5.getText());
            label_PID.setText("PID:"+nowpcb.getPID());
            label_rank.setText("Rank:"+nowpcb.getRank());
            label_Statement.setText("Statement:"+nowpcb.getStatement());
            label_Time.setText("Time:"+nowpcb.getTime());
            label_start_address.setText("Main_memory_start_address:"+nowpcb.getMain_memory_start_address());
            label_memory_length.setText("Main_memory_length:"+nowpcb.getMain_memory_length());
            label_PID.setVisible(true);
            label_Time.setVisible(true);
            label_memory_length.setVisible(true);
            label_Statement.setVisible(true);
            label_start_address.setVisible(true);
            label_rank.setVisible(true);
        }
    }
    //鼠标触摸事件,当鼠标接触时显示详细信息
    public void show_pcb_detail6(MouseEvent mouseEvent) {
        if(!pcb6.getText().equals("null")){
            PCB nowpcb = PDI.selectBy_PID(pcb6.getText());
            label_PID.setText("PID:"+nowpcb.getPID());
            label_rank.setText("Rank:"+nowpcb.getRank());
            label_Statement.setText("Statement:"+nowpcb.getStatement());
            label_Time.setText("Time:"+nowpcb.getTime());
            label_start_address.setText("Main_memory_start_address:"+nowpcb.getMain_memory_start_address());
            label_memory_length.setText("Main_memory_length:"+nowpcb.getMain_memory_length());
            label_PID.setVisible(true);
            label_Time.setVisible(true);
            label_memory_length.setVisible(true);
            label_Statement.setVisible(true);
            label_start_address.setVisible(true);
            label_rank.setVisible(true);
        }
    }
    //鼠标离开事件,当鼠标离开时详细信息消失
    public void hide_pcb_detail(MouseEvent mouseEvent) {
        label_PID.setVisible(false);
        label_Time.setVisible(false);
        label_memory_length.setVisible(false);
        label_Statement.setVisible(false);
        label_start_address.setVisible(false);
        label_rank.setVisible(false);
    }
    //更新内存图形化界面
    private List<Label> update_picture(List<Label> a){
        //移除旧标签
        for(int oldlabel=0;oldlabel<a.size();oldlabel++){
            Main_pane.getChildren().remove(a.get(oldlabel));
        }
        //添加新标签块
        int labelnumber;
        List<PCB> list =PDI.select(0,10);
        List<Label> newlist = new ArrayList<>();
        //有几个进程添加几个标签
        for (labelnumber=0;labelnumber<list.size();labelnumber++){
            PCB nowpcb = list.get(labelnumber);
            Label pcb_label = new Label(nowpcb.getPID());
            pcb_label.setWrapText(true);
            //设置边框为黑色
            pcb_label.setStyle("-fx-border-color: black");
            //在运行的进程显示为绿色
            if(nowpcb.getStatement().equals("running"))
                pcb_label.setStyle(pcb_label.getStyle()+";-fx-background-color: green");
            //挂起的进程显示为红色
            else if(nowpcb.getStatement().equals("hangup"))
                pcb_label.setStyle(pcb_label.getStyle()+";-fx-background-color: red");
            //根据所占内存大小和内存位置显示
            pcb_label.setLayoutX(nowpcb.getMain_memory_start_address()*10);
            pcb_label.setLayoutY(label_memory.getLayoutY());
            pcb_label.setPrefWidth(nowpcb.getMain_memory_length()*10);
            pcb_label.setPrefHeight(label_memory.getHeight());
            Main_pane.getChildren().add(pcb_label);
            //当鼠标触摸时显示详细信息
            pcb_label.setOnMouseEntered(mouseEvent -> {
                label_PID.setText("PID:"+nowpcb.getPID());
                label_rank.setText("Rank:"+nowpcb.getRank());
                label_Statement.setText("Statement:"+nowpcb.getStatement());
                label_Time.setText("Time:"+nowpcb.getTime());
                label_start_address.setText("Main_memory_start_address:"+nowpcb.getMain_memory_start_address());
                label_memory_length.setText("Main_memory_length:"+nowpcb.getMain_memory_length());
                label_PID.setVisible(true);
                label_Time.setVisible(true);
                label_memory_length.setVisible(true);
                label_Statement.setVisible(true);
                label_start_address.setVisible(true);
                label_rank.setVisible(true);
            });
            //当鼠标离开时隐藏详细信息
            pcb_label.setOnMouseExited(mouseEvent -> {
                label_PID.setVisible(false);
                label_Time.setVisible(false);
                label_memory_length.setVisible(false);
                label_Statement.setVisible(false);
                label_start_address.setVisible(false);
                label_rank.setVisible(false);
            });
            newlist.add(pcb_label);
            pcbsix.get(labelnumber).setText(list.get(labelnumber).getPID());
        }
        while (labelnumber<6){
            pcbsix.get(labelnumber).setText("null");
            labelnumber++;
        }
        return newlist;
    }

}
Main.fxml
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.paint.*?>
<?import javafx.scene.shape.*?>
<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<GridPane alignment="center" hgap="10" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="800.0" prefWidth="1280.0" vgap="10" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.csu.schedule.windows.Controller_Main">
   <columnConstraints>
      <ColumnConstraints />
      <ColumnConstraints />
      <ColumnConstraints />
      <ColumnConstraints maxWidth="0.0" minWidth="0.0" prefWidth="0.0" />
      <ColumnConstraints maxWidth="0.0" minWidth="0.0" prefWidth="0.0" />
      <ColumnConstraints />
      <ColumnConstraints />
      <ColumnConstraints />
      <ColumnConstraints />
      <ColumnConstraints />
      <ColumnConstraints />
      <ColumnConstraints />
      <ColumnConstraints />
      <ColumnConstraints />
      <ColumnConstraints />
      <ColumnConstraints />
      <ColumnConstraints />
   </columnConstraints>
   <rowConstraints>
      <RowConstraints />
      <RowConstraints />
      <RowConstraints />
      <RowConstraints />
      <RowConstraints />
      <RowConstraints />
      <RowConstraints />
      <RowConstraints maxHeight="0.0" minHeight="0.0" prefHeight="0.0" />
      <RowConstraints maxHeight="0.0" minHeight="0.0" prefHeight="0.0" />
      <RowConstraints />
      <RowConstraints />
      <RowConstraints />
      <RowConstraints />
      <RowConstraints />
      <RowConstraints />
      <RowConstraints />
      <RowConstraints />
      <RowConstraints />
      <RowConstraints />
      <RowConstraints />
      <RowConstraints />
      <RowConstraints />
      <RowConstraints />
      <RowConstraints />
      <RowConstraints />
      <RowConstraints maxHeight="0.0" minHeight="0.0" prefHeight="0.0" />
      <RowConstraints maxHeight="0.0" minHeight="0.0" prefHeight="0.0" />
   </rowConstraints>
   <children>
      <AnchorPane fx:id="Main_pane" layoutX="1.0" layoutY="2.0" prefHeight="709.0" prefWidth="1001.0" GridPane.columnIndex="9" GridPane.rowIndex="10">
         <children>
            <ToggleButton fx:id="ready" layoutX="36.0" layoutY="50.0" mnemonicParsing="false" onAction="#ChooseQuery" prefHeight="23.0" prefWidth="96.0" selected="true" text="就绪队列">
               <toggleGroup>
                  <ToggleGroup fx:id="Querygroup" />
               </toggleGroup>
            </ToggleButton>
            <ToggleButton fx:id="running" layoutX="132.0" layoutY="50.0" mnemonicParsing="false" onAction="#ChooseQuery" prefHeight="23.0" prefWidth="96.0" text="运行队列" toggleGroup="$Querygroup" />
            <ToggleButton fx:id="hangup" layoutX="228.0" layoutY="50.0" mnemonicParsing="false" onAction="#ChooseQuery" prefHeight="23.0" prefWidth="96.0" text="挂起队列" toggleGroup="$Querygroup" />
            <ToggleButton fx:id="reserve" layoutX="324.0" layoutY="50.0" mnemonicParsing="false" onAction="#ChooseQuery" prefHeight="23.0" prefWidth="96.0" text="后备队列" toggleGroup="$Querygroup" />
            <Label fx:id="user" layoutX="36.0" layoutY="14.0" prefHeight="24.0" prefWidth="120.0" text="用户:m7hna" />
            <Label fx:id="nameOfDR" layoutX="540.0" layoutY="14.0" prefHeight="24.0" prefWidth="96.0" text="系统日志:" />
            <TableView fx:id="Process" layoutX="33.0" layoutY="101.0" prefHeight="200.0" prefWidth="438.0">
               <columns>
                  <TableColumn fx:id="PID" editable="false" prefWidth="150.0" sortable="false" text="PID" />
                  <TableColumn fx:id="Time" editable="false" minWidth="0.0" prefWidth="69.0" sortable="false" text="Time" />
                  <TableColumn fx:id="Rank" editable="false" minWidth="0.0" prefWidth="61.0" sortable="false" text="Rank" />
                  <TableColumn fx:id="Statement" editable="false" minWidth="0.0" prefWidth="104.0" sortable="false" text="Statement" />
                  <TableColumn fx:id="main_memory_start_address" editable="false" minWidth="0.0" prefWidth="267.0" sortable="false" text="main_memory_start_address" />
                  <TableColumn fx:id="main_memory_length" editable="false" minWidth="0.0" prefWidth="207.0" sortable="false" text="main_memory_length" />
               </columns>
            </TableView>
            <Button layoutX="33.0" layoutY="301.0" mnemonicParsing="false" onAction="#on_button_add" prefHeight="24.0" prefWidth="96.0" text="添加作业" />
            <Button fx:id="hangup_button" layoutX="129.0" layoutY="301.0" mnemonicParsing="false" onAction="#on_button_hangup" prefHeight="24.0" prefWidth="60.0" text="挂起" />
            <Button layoutX="189.0" layoutY="301.0" mnemonicParsing="false" onAction="#on_button_remove" prefHeight="24.0" prefWidth="60.0" text="解挂" />
            <TextArea fx:id="dailyRecord" editable="false" layoutX="548.0" layoutY="50.0" prefHeight="165.0" prefWidth="341.0" />
            <Button layoutX="303.0" layoutY="301.0" mnemonicParsing="false" onAction="#on_button_Priority" prefHeight="24.0" prefWidth="78.0" text="优先级" />
            <Button layoutX="381.0" layoutY="301.0" mnemonicParsing="false" onAction="#on_button_timeSlice" prefHeight="24.0" prefWidth="90.0" text="时间片" />
            <Button layoutX="243.0" layoutY="301.0" mnemonicParsing="false" onAction="#on_button_terminate" prefHeight="24.0" prefWidth="60.0" text="结束" />
            <Button fx:id="button_start" layoutX="818.0" layoutY="258.0" mnemonicParsing="false" onAction="#on_button_start" prefHeight="24.0" prefWidth="120.0" text="开始" />
            <Label layoutX="14.0" layoutY="337.0" text="内存状态:" />
            <Label fx:id="label_memory" layoutX="1.0" layoutY="361.0" prefHeight="180.0" prefWidth="1000.0" style="-fx-border-color: black;" />
            <Label fx:id="pcb1" layoutX="1.0" layoutY="362.0" onMouseEntered="#show_pcb_detail1" onMouseExited="#hide_pcb_detail" prefHeight="30.0" prefWidth="200.0" style="-fx-border-color: black;" text="null" wrapText="true" />
            <Label fx:id="pcb2" layoutX="1.0" layoutY="392.0" onMouseEntered="#show_pcb_detail2" onMouseExited="#hide_pcb_detail" prefHeight="30.0" prefWidth="200.0" style="-fx-border-color: black;" text="null" />
            <Label fx:id="pcb3" layoutX="1.0" layoutY="422.0" onMouseEntered="#show_pcb_detail3" onMouseExited="#hide_pcb_detail" prefHeight="30.0" prefWidth="200.0" style="-fx-border-color: black;" text="null" />
            <Label fx:id="pcb5" layoutX="1.0" layoutY="481.0" onMouseEntered="#show_pcb_detail4" onMouseExited="#hide_pcb_detail" prefHeight="30.0" prefWidth="200.0" style="-fx-border-color: black;" text="null" />
            <Label fx:id="pcb4" layoutX="1.0" layoutY="451.0" onMouseEntered="#show_pcb_detail5" onMouseExited="#hide_pcb_detail" prefHeight="30.0" prefWidth="200.0" style="-fx-border-color: black;" text="null" />
            <Label fx:id="pcb6" layoutX="1.0" layoutY="511.0" onMouseEntered="#show_pcb_detail6" onMouseExited="#hide_pcb_detail" prefHeight="30.0" prefWidth="200.0" style="-fx-border-color: black;" text="null" />
            <Label fx:id="label_PID" layoutX="548.0" layoutY="215.0" text="PID:AutoCreated7011" visible="false" />
            <Label fx:id="label_Time" layoutX="548.0" layoutY="240.0" text="Time:11" visible="false" />
            <Label fx:id="label_rank" layoutX="548.0" layoutY="264.0" text="Rank:11" visible="false" />
            <Label fx:id="label_Statement" layoutX="548.0" layoutY="288.0" text="Statement:ready" visible="false" />
            <Label fx:id="label_start_address" layoutX="548.0" layoutY="310.0" text="main_memory_start_address:22" visible="false" />
            <Label fx:id="label_memory_length" layoutX="548.0" layoutY="337.0" text="main_memory_length:22" visible="false" />
         </children>
      </AnchorPane>
   </children>
</GridPane>
Control_Add
package org.csu.schedule.windows;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
import org.csu.schedule.persistence.Impl.ReserveDAOImpl;


public class Controller_Add extends Application {

    public AnchorPane pane_add;
    public Button button_add;
    public TextField textfiled_PID;
    public TextField textfiled_rank;
    public Label label_rank;
    public Button button_clear;
    Stage stage = new Stage();

    @Override
    public void start(Stage primaryStage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("add.fxml"));
        primaryStage.setTitle("添加作业");
        primaryStage.setScene(new Scene(root, 600, 400));
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }

    public void showWindow() throws Exception {
        start(stage);
    }

    public void on_button_add() {
        int a = Integer.parseInt(textfiled_rank.getText());
        int b = (int)(1+Math.random()*10);
        ReserveDAOImpl RDI = new ReserveDAOImpl();
        RDI.add(textfiled_PID.getText(),a,b);
        Stage stage1 = (Stage) button_add.getScene().getWindow();
        stage1.close();
    }

    public void on_button_clear() {
        textfiled_PID.clear();
        textfiled_rank.clear();
    }

}
add.fxml
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.*?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane fx:id="pane_add" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8"
            xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.csu.schedule.windows.Controller_Add">
   <Label  layoutX="123.0" layoutY="83.0" text="PID"/>
   <Button fx:id="button_add" layoutX="333.0" layoutY="200.0" mnemonicParsing="false" onAction="#on_button_add"
           prefHeight="36.0" prefWidth="96.0" text="确认添加"/>
   <TextField fx:id="textfiled_PID" layoutX="187.0" layoutY="77.0"/>
   <TextField fx:id="textfiled_rank" layoutX="187.0" layoutY="142.0"/>
   <Label fx:id="label_rank" layoutX="120.0" layoutY="148.0" text="rank"/>
   <Label layoutX="123.0" layoutY="252.0"/>
   <Button fx:id="button_clear" layoutX="187.0" layoutY="200.0" mnemonicParsing="false" onAction="#on_button_clear"
           prefHeight="36.0" prefWidth="96.0" text="清空"/>
</AnchorPane>

六、实验结论及截图
在这里插入图片描述

七、实验小结
通过本次实验,我学习了对一个项目的架构,对操作系统有了更深层次的了解,同时我的编码水平有了很大的提升,同时也初步学会了javafx这个工具的应用,也稍微了解了一点点线程的编程概念,总之,全方面都有了提升,这次实验对我帮助很大。
对于本次实验暴露的问题,我发现自己编程基础相对薄弱,会因为一些不应该的困难卡住。
就项目而言,还有一些地方可以优化,例如界面的美化,功能的完善,以及更多的信息,更友好的界面设计,都是可以提升的地方,后期可以优化。还有一点,由于项目有涉及线程和数据库,运行时会出现卡顿和与数据库断开连接的现象,一小段时间后会恢复正常,我现在的知识还无法解决这个问题,留待以后解决。

一、实验目的 多道系统中,进程与进程之间存在同步与互斥关系。当就绪进程数大于处理机数时,需按照某种策略决定哪些进程先占用处理机。在可变分区管理方式下,采用首次适应算法实现主存空间的分配和回收。 本实验模拟实现处理机调度及内存分配及回收机制,以对处理机调度的工作原理以及内存管理的工作过程进行更深入的了解。 二、实验内容及要求 1.实验内容 (1)选择一个调度算法实现处理机调度; (2)结合(1)实现主存储器空间的分配和回收。 2.实验具体要求 (1)设计一个抢占式优先权调度算法实现处理机调度的程序,并且实现在可变分区管理方式下,采用首次适应算法实现主存空间的分配和回收。 (2)PCB内容包括:进程名/PID;要求运行时间(单位时间);优先权;状态;进程属性:独立进程、同步进程(前趋、后继)。 (3)可以随机输入若干进程,可随时添加进程,并按优先权排序; (4)从就绪队首选进程运行:优先权-1;要求运行时间-1;要求运行时间为0时,撤销该进程;一个时间片结束后重新排序,进行下轮调度; (5)考虑两个处理机,考虑同步进程的处理机分配问题,每次调度后,显示各进程状态,运行进程要显示在哪个处理机上执行。 (6)规定道数,设置后备队列和挂起状态。若内存中进程少于规定道数,可自动从后备队列调度一作业进入。被挂起进程入挂起队列,设置解挂功能用于将制定挂起进程解挂入就绪队列。 (7)结合实验一pcb增加所需主存大小,主存起始位置;采用首次适应算法分配主存空间。 (8)自行假设主存空间大小,预设操作系统所占大小并构造未分分区表。表目内容:起址、长度、状态(未分/空表目)。 (9)进程完成后,回收主存,并与相邻空闲分区合并。 (10)最好采用图形界面;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值