java输入YN控制循环_java实现SP00LING假脱机输入输出技术模拟

1896087372.jpg

234.jpg

Basic Framework

3907811371.png

缓冲技术.png

1857890937.png

屏幕快照 2017-12-22 12.09.12.png

进程调度算法

进程调度采用随机算法,这与进程输出信息的随机性相一致。两个请求输出的用户进程的调度概率各为45%,SP00LING输出进程为10%,这由随机数发生器产生的随机数来模拟决定。

进程状态

进程有5种状态:

0为可执行态;

1为等待状态1,表示输出井满,请求输出的用户进程等待;

2为等待状态2,表示请求输出井空,SP00LING输出进程等待;

3为等待状态3,表示请求输出井满,请求输出的用户进程等待;

4为结束态,进程执行完成。进程基本状态有3种,分别为可执行、等待和结束。可执行态就是进程正在运行或等待调度的状态;等待状态又分为等待状态1、等待状态2和等待状态3。

状态变化的条件为:

①进程执行完成时,置为“结束”态。

②服务程序在将输出信息送输出井时,如发现输出井已满,将调用进程置为“等待状态1”。

③SP00LING进程在进行输出时,若输出井空,则进入“等待状态2”。

④SP00LING进程输出一个信息块后,应立即释放该信息块所占的输出井空间,并将正在等待输出的进程置为“可执行状态”。

⑤服务程序在输出信息到输出井并形成输出请求信息块后,若SP00LING进程处于等待态,则将其置为“可执行状态”。

⑥当用户进程申请请求输出块时,若没有可用请求块时,调用进程进人“等待状态3”。

PCB.java

package Spooling;

public class PCB {

int ID;//进程标识数

int status;//进程状态

int outputFileCount;//要输出的文件数

int outPut_X;//进程输出时的临时变量

}

requireBlock.java

package Spooling;

public class requireBlock {

int requireName; //请求进程名

int length;//本次输出信息长度

int outputHeadAddress;//信息在输出井的首地址

}

Manage.java

package Spooling;

import java.util.Random;

import javax.swing.JTextArea;

import javax.swing.JTextField;

public class Manage extends Thread{

PCB pcb[];

requireBlock requireblock[];

int buffer[][];

int outputBufferSpace[];//可使用的输出井buffer空间

int outputBufferPointer[][]; //输出井buffer空闲和满指针

int requireblockNumber; //requireblock的剩余数量

int requireblockOutputPointer; //要输出的第一个reqblock指针

int requireblockFreePointer; //第一个空闲reqblock指针

double random; //用于调度三个进程的控制随机数

int output1; //用户进程1已生成的文件数

int output2; //用户进程2已生成的文件数

int output_1; //用户进程1已输出的文件数

int output_2; //用户进程2已输出的文件数

int x; //随机生成的数据0~9

int i; //临时控制变量

Random x1; //辅助生成随机数据x:0~9

Spooling spooling;

public Manage( Spooling spooling ){//对各进程的数据初始化

output1 = 0;

output2 = 0;

output_1 = 0;

output_2 = 0;

pcb = new PCB[4];

requireblock = new requireBlock[10];

buffer = new int[3][100];

outputBufferSpace = new int[3];

outputBufferSpace[1] = 100;

outputBufferSpace[2] = 100;

outputBufferPointer = new int[3][4];

outputBufferPointer[1][0] = 0;

outputBufferPointer[2][0] = 0;

requireblockNumber = 10;

requireblockOutputPointer = 0;

requireblockFreePointer = 0;

x1 = new Random();

for( i = 0; i < 4; i++ ){

pcb[ i ] = new PCB();

}

for( i = 0; i < 10; i++ ){

requireblock[ i ] = new requireBlock();

}

for( i = 1; i <=3; i++ ){

pcb[ i ].status = 0;

}

this.spooling = spooling;//对各进程的数据初始化完毕 把这个传过来有助于更新界面内容

}

public void run(){ //进程调度

do{ //while循环

random = Math.random();//产生一个随机数,控制进程调度,令用户进程概率为45%,Spooling进程为10%

if( random <= 0.45 && pcb[ 1 ].status == 0 ){ //调度用户进程1

spooling.textArea4.append( "调度用户进程1\n" );

try{

sleep( 500 );

}

catch( InterruptedException e ){

e.printStackTrace();

}

///调用用户函数去生成文件填入输出井生成请求块

output1 = user( 1, output1, spooling.textArea1, spooling.field1 );

}

else if( random >0.45 && random <= 0.9 && pcb[ 2 ].status == 0 ){ //调度用户进程2

spooling.textArea4.append( "调度用户进程2\n" );

try{

sleep( 500 );

}

catch( InterruptedException e ){

e.printStackTrace();

}

output2 = user( 2, output2, spooling.textArea2, spooling.field2 );

}

else if( random >0.9 && random <= 1 && pcb[3].status == 0 ){ //调度spooling进程

spooling.textArea4.append("调度Spooling进程\n");

try{

sleep( 500 );

}

catch( InterruptedException e ){

e.printStackTrace();

}

spooling1();

}

}

while( pcb[1].status != 4 || pcb[2].status != 4 || pcb[3].status != 4 ); // 当都是结束状态曾程序运行完成

spooling.textArea4.append("程序运行完毕\n"); //进程调度结束

}

public int user( int name, int out, JTextArea textarea, JTextField field ){ //用户进程 返回已经生成的文件数目

pcb[ name ].ID = name;

pcb[ name ].outputFileCount = Integer.parseInt( field.getText() );

while( out != pcb[ name ].outputFileCount ){//判断进程所要输出的文件是否输出完毕的while循环

outputBufferPointer[ name ][ 1 ] = outputBufferPointer[ name ][ 0 ];

do{ //判断进程的一个文件是否输出完毕的while循环

x = x1.nextInt( 9 );//x为每次随机生成的数据0~9,送入pcb.x

pcb[ name ].outPut_X = x;

if( outputBufferSpace[ name ] == 0 ){ //若输出井buffer满,变为等待状态1,转调度程序

pcb[ name ].status = 1;

//一个文件的长度是未知的在创建的过程中如果发现井满了要退回去

if( outputBufferPointer[ name ][ 0 ] >= outputBufferPointer[ name ][5] ){

outputBufferSpace[ name ] = outputBufferSpace[ name ] + outputBufferPointer[ name ][ 0] - outputBufferPointer[ name ][ 1 ];//将空间释放

}

else{

outputBufferSpace[ name ] = outputBufferSpace[ name ] + 100 + outputBufferPointer[ name ][ 0] + outputBufferPointer[ name ][ 1 ];

}

outputBufferPointer[ name ][ 0 ] = outputBufferPointer[ name ][ 1 ]; //将空间释放

textarea.append( "第" + ( out + 1 ) + "个文件缺少输出井" );

textarea.append( "进入等待状态1\n" );

try{

sleep( 500 );

}

catch( InterruptedException e ){

e.printStackTrace();

}

return out;

}

else{//若输出井没满

buffer[ name ][ outputBufferPointer[ name ][ 0 ] ] = pcb[ name ].outPut_X; //进程的输出信息PCB[i].x送buffer[i][ outputBufferPointer[i][0]]

outputBufferSpace[ name ] = outputBufferSpace[ name ] - 1; //输出井空闲个数减1

outputBufferPointer[ name ][ 0 ] = ( outputBufferPointer[ name ][ 0 ] + 1 ) % 100; //修改空缓冲区指针outputBufferPointer[i][0]前进1

}

}

while( x != 0 ); //判断进程的一个文件是否输出完毕的while循环结束

if( outputBufferPointer[ name ][ 0 ] == 0 ){

textarea.append( (out + 1) + " " + outputBufferPointer[ name ][ 1 ] + " ~ " + " 99 " + outputBufferSpace[ name ] + " ");

}

else{

textarea.append( (out + 1) + " " + outputBufferPointer[ name ][ 1 ] + " ~ " + ( outputBufferPointer[ name ][ 0 ] - 1 ) + " " + outputBufferSpace[ name ] + " " );

}

try{

sleep( 500 );

}

catch( InterruptedException e ){

e.printStackTrace();

}

out++; //成功生成了一个文件

//接下来要生成相应的请求块

if( requireblockNumber == 0 ){//若没有空闲请求输出块,转为等待状态3

pcb[ name ].status = 3;

textarea.append( "缺少请求输出块" );

textarea.append( "进入等待状态3 \n" );

try{

sleep( 500 );

}

catch( InterruptedException e ){

e.printStackTrace();

}

return out;

}

else{ //若有空闲请求输出块

requireblock[ requireblockFreePointer ].outputHeadAddress = outputBufferPointer[ name ][ 1 ]; //将文件在输出井的位置填入空闲请求块

if( outputBufferPointer[ name ][ 0 ] >= outputBufferPointer[ name ][ 1 ] ){ //将文件在输出井的长度填入空闲请求块

requireblock[ requireblockFreePointer ].length = outputBufferPointer[ name ][ 0 ] - outputBufferPointer[ name ][ 1 ];

}

else{

requireblock[ requireblockFreePointer ].length = 100 - outputBufferPointer[ name ][ 1 ] + outputBufferPointer[ name ][ 0 ];

}

requireblock[ requireblockFreePointer ].requireName = name; //将进程名i填入请求块

textarea.append( "获得请求输出块" + Integer.toString( requireblockFreePointer +1 ) + "\n");

requireblockFreePointer = ( requireblockFreePointer + 1 ) % 10;//修改空闲请求块指针

requireblockNumber--;

if( pcb[ 3 ].status == 2 ){ //若SPOOLING进程是等待状态,则唤醒SPOOLING进程

pcb[ 3 ].status = 0;

}

}

}//判断进程所要输出的文件是否输出完毕的while循环结束

textarea.append( "进程" + name + "输出完毕!" );//文件输出完毕,修改状态为结束,转进程调度

pcb[ name ].status = 4;

return out;

}

public void spooling1(){

while( requireblockNumber != 10 ){ //判断请求输出块是否为空的while循环

//若请求输出块不为空

StringBuffer stringBuffer = new StringBuffer( 100 );

for ( i = 0; i

stringBuffer.append( buffer[ requireblock[ requireblockOutputPointer ].requireName ][ requireblock[ requireblockOutputPointer ].outputHeadAddress] );

requireblock[ requireblockOutputPointer ].outputHeadAddress = ( requireblock[ requireblockOutputPointer ].outputHeadAddress + 1 )%100;

}

if( requireblock[ requireblockOutputPointer ].requireName == 1){

output_1++;

spooling.textArea3.append( "User1第" + output_1 + "个文件:");

}

else{

output_2++;

spooling.textArea3.append( "User2第" + output_2 + "个文件:");

}

spooling.textArea3.append( stringBuffer.toString() + "\n" );

try{

sleep( 500 );

}

catch( InterruptedException e ){

e.printStackTrace();

}

//释放相应输出井,即修改相应的输出井计数outputBufferSpace

outputBufferSpace[ requireblock[ requireblockOutputPointer ].requireName ] = outputBufferSpace[ requireblock[ requireblockOutputPointer ].requireName ] + requireblock[ requireblockOutputPointer ].length;

requireblockOutputPointer = ( requireblockOutputPointer + 1 )%10;

requireblockNumber++;

for( int k = 1; k <= 2; k++ ){

if( pcb[ k ].status == 3 ){ //有等待请求输出块的进程,唤醒没有请求块的进程 一次输出进程完成只能解禁一个请求块所以要完成一个就切断

//应该看先是否有等待请求块的进程,这样可以尽早释放相应的井空间

pcb[ k ].status = 0;

requireblock[ requireblockFreePointer ].outputHeadAddress = outputBufferPointer[ k ][ 1 ];//将文件在输出井的位置填入空闲请求块

if( outputBufferPointer[ k ][ 0 ] >= outputBufferPointer[ k ][ 1 ] ){ //将文件在输出井的长度填入空闲请求块

requireblock[ requireblockFreePointer ].length = outputBufferPointer[ k ][ 1 ];

}

else{

requireblock[ requireblockFreePointer ].length = 100 - outputBufferPointer[ k ][ 1] + outputBufferPointer[ k ][ 0 ];

}

requireblock[ requireblockFreePointer ].requireName = k;//将进程名i填入请求块

if( k ==1 ){

spooling.textArea1.append("第" + output1 + "个文件获得请求输出块" + ( Integer.toString( requireblockFreePointer + 1 ) ) + "\n" );

}

if( k == 2 ){

spooling.textArea2.append("第" + output2 + "个文件获得请求输出块" + ( Integer.toString( requireblockFreePointer + 1 ) ) + "\n" );

}

requireblockFreePointer = ( requireblockFreePointer +1 )%10;//修改空闲请求块指针

requireblockNumber--; //空闲请求块数减1

if( pcb[ 3 ].status == 2 ){ //若SPOOLING进程是等待状态,则唤醒SPOOLING进程

pcb[ 3 ].status = 0;

}

return; //完成一个就切断, 可能两个都等待请求块,但先满足一个吧

}

}

for( int k =1; k <=2; k++ ){

if( pcb[ k ].status ==1 ){ //有等待输出井的进程,唤醒相应进程

pcb[ k ].status = 0;

return;

}

}

}//判断请求输出块是否为空的while循环结束

if( pcb[ 1 ].status ==4 && pcb[ 2 ].status ==4 ){//进程1、2结束后输出进程结束

pcb[ 3 ].status = 4;

spooling.textArea3.append( " Spooling输出进程结束" );

return;

}

else{

spooling.textArea3.append( "调度spooling输出程序,请求块空,输出进程转入状态2\n" );

pcb[ 3 ].status = 2;

}

}

}

Spooling.java

package Spooling;

import java.awt.BorderLayout;

import java.awt.Container;

import java.awt.FlowLayout;

import java.awt.GridLayout;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JPanel;

import javax.swing.JScrollPane;

import javax.swing.JTextArea;

import javax.swing.JTextField;

import javax.swing.SwingConstants;

public class Spooling extends JFrame implements ActionListener{

JPanel panel1;

JPanel panel2;

JPanel panel3;

JTextField field1;

JTextField field2;

JScrollPane p1;

JScrollPane p2;

JScrollPane p3;

JScrollPane p4;

JTextArea textArea1;

JTextArea textArea2;

JTextArea textArea3;

JTextArea textArea4;

JButton button;

Manage manage;

public Spooling(){

//界面构造函数

manage = new Manage( this );

Container container = this.getContentPane();

container.setLayout( new BorderLayout() );

field1 = new JTextField( 3 );//设置panel1

field2 = new JTextField( 3 );

button = new JButton( "运行" );

button.addActionListener( this );

panel1 = new JPanel();

panel1.setLayout( new FlowLayout() );

panel1.add( new JLabel( "用户进程1文件数:", SwingConstants.RIGHT ) );

panel1.add( field1 );

panel1.add( new JLabel( "用户进程2文件数:", SwingConstants.RIGHT) );

panel1.add( field2 );

panel1.add( button );

//设置panel1完毕

textArea1 = new JTextArea( 80,100 );//设置panel2

textArea2 = new JTextArea( 112,400 );

textArea1.append( "用户进程1的文件生成情况及状态变换\n文件序号 位 置 剩余空间 状态\n" );

textArea2.append("用户进程2的文件生成情况及状态变换\n文件序号 位 置 剩余空间 状态\n");

p1 = new JScrollPane( textArea1 );

p2 = new JScrollPane( textArea2 );

panel2 = new JPanel();

panel2.setLayout ( new GridLayout( 1,2 ) );

panel2.add( p1 );

panel2.add( p2 );

//设置panel2完毕

textArea3 = new JTextArea( 15,400 );//设置panel3

textArea4 = new JTextArea( 15,150 );

textArea3.append( "打印输出\n" );

textArea4.append("主程序调度\n");

p3 = new JScrollPane( textArea3 );

p4 = new JScrollPane( textArea4 );

panel3 = new JPanel();

panel3.setLayout( new GridLayout( 1,2 ) );

panel3.add( p3 );

panel3.add( p4 );

container.add( panel1, BorderLayout.NORTH );//设置窗口

container.add( panel2 ,BorderLayout.CENTER );

container.add( panel3, BorderLayout.SOUTH );

this.setSize( 1200,600 );

this.setLocation( 100,100 );

this.setTitle( "Spooling" );

this.setVisible( true );

this.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );//设置窗口完毕

}

public void actionPerformed( ActionEvent e ){

manage.start();

}

public static void main( String args[] ){

Spooling spooling = new Spooling();

}

}

Running Effect

2365909561.png

屏幕快照 2017-12-22 12.09.01.png

Source Download

Please click the address->

Summarize

3585656334.jpg

SP00LING 输出模拟系统主控流程图.jpg

1282692940.jpg

SP00LING 输出服务程序由两个用户进程调用流程图.jpg

2136339961.jpg

SPOOLING 输出进程流程图.jpg

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值