读者-写者问题的读写操作限制(包括读者优先和写者优先):
1) 写-写互斥,即不能有两个写者同时进行写操作。
2) 读-写互斥,即不能同时有一个线程在读,而另一个线程在写。
3) 读-读允许,即可以有一个或多个读者在读。
读者优先的附加限制:如果一个读者申请进行读操作时已有另一个读者正在进行读操作,则该读者可直接开始读操作。
写者优先的附加限制:如果一个读者申请进行读操作时已有另一写者在等待访问共享资源,则该读者必须等到没有写者处于等待状态后才能开始读操作。
运行结果显示要求:要求在每个线程创建、发出读写操作申请、开始读写操作和结束读写操作时分别显示一行提示信息,以确定所有处理都遵守相应的读写操作限制。
测试数据简介:数据数据包括n行测试数据,分别描述创建的n个线程是读者还是写者,以及读写操作的开始时间和持续时间。每行测试数据包括四个字段,各个字段间用空格分隔。第一字段为一个正整数,表示线程序号。第二字段表示相应线程角色,R表示读者,w表示写者。第三字段为一个正数,表示读写操作的开始时间:线程创建后,延迟相应时间(单位为秒)后发出对共享资源的读写申请。第四字段为一个正数,表示读写操作的持续时间。
package 进程同步; public class Jinchengtongbu { public static void main(String[] args) { // TODO Auto-generated method stub String name[]={" 进程序号", " 读写者", " ", "开始时间"," 运行时间"}; for(int i=0;i<name.length;i++){ System.out.print(name[i]); } System.out.println(); String arr[][]= {{"1","r","3" ,"5"}, {"2","w","5","5"},{"3","r","4","2"},{"4","w","10","1"}}; int j,i; for(j=0;j<arr.length;j++){ for(i=0;i<arr[j].length;i++){ System.out.print( " "+ arr[j][i]); } System.out.println(); } int a = Integer.parseInt(arr[0][2]);//从0开始最好 int b = Integer.parseInt(arr[1][2]); int c = Integer.parseInt(arr[2][2]); int d = Integer.parseInt(arr[3][2]); int sort[]={a,b,c,d}; // Arrays.sort(sort); System.out.println(); for(int k=0;k<sort.length;k++){ for(int o=k+1;o<sort.length;o++){ if(sort[o]<sort[k]){ String f= arr[k][2]; String s= arr[k][0]; String m= arr[k][1]; String n= arr[k][3]; int su = sort[o]; arr[k][2]=arr[o][2]; arr[k][0]=arr[o][0]; arr[k][1]=arr[o][1]; arr[k][3]=arr[o][3]; sort[o]=sort[k]; arr[o][2]= f; arr[o][0]= s; arr[o][1]= m; arr[o][3]= n; sort[k] = su; } } } for( i=0;i<name.length;i++){ System.out.print(name[i]); } System.out.println(); for(j=0;j<arr.length;j++){ for(i=0;i<arr[j].length;i++){ System.out.print( " "+ arr[j][i]); } System.out.println(); } int a1 = Integer.parseInt(arr[0][2]);//第三列 int a2 = Integer.parseInt(arr[0][3]);//第四列 int a3 = Integer.parseInt(arr[0][0]);//第一列 int a4 = 0;//用来结束程序 int t1= 0;//程序开始后计时 int b1 = Integer.parseInt(arr[1][2]); int b2 = Integer.parseInt(arr[1][3]); int b3 = Integer.parseInt(arr[1][0]); int b4 = 0; int t2= 0; int c1 = Integer.parseInt(arr[2][2]); int c2 = Integer.parseInt(arr[2][3]); int c3 = Integer.parseInt(arr[2][0]); int c4 = 0; int t3= 0; int d1 = Integer.parseInt(arr[3][2]); int d2 = Integer.parseInt(arr[3][3]); int d3 = Integer.parseInt(arr[3][0]); int d4 = 0; int t4= 0; int ci1 = 0,ci2 = 0,ci3 = 0,ci4 = 0; int sam = 0;//空闲 int num = 0; for(int t=0;t<30;t++) { System.out.println("时间:"+num); num=num+1; if((a1==t && arr[0][1]=="r" ||( a1<=t && arr[0][1]=="w" && sam==0 )) && ci1==0){ System.out.println("开始"+a3+"号程序"); ci1=ci1+1;//为了只输出一次 a4 = a2; } if(arr[0][1]=="w" && ci1==1 ){//ci1表示开始 t1=t1+1; if(t1==a4) { a4=0; System.out.println(a3+"号程序结束"); arr[0][1]="ch"; t=t-t1+1;//把写者踢出 sam = 0; } continue; } if(a4!=0) { t1=t1+1; sam = sam+1; if(t1==a4) { System.out.println(a3+"号程序结束"); sam = sam-a4; a4=0; } } if((b1==t && arr[1][1]=="r" ||( b1<=t && arr[1][1]=="w" && sam==0 ))&&ci2==0){ System.out.println("开始"+b3+"号程序"); ci2=ci2+1; b4 = b2; } if(arr[1][1]=="w" && ci2==1 ){ t2=t2+1; if(t2==b4) { b4=0; System.out.println(b3+"号程序结束"); arr[1][1]="ch"; t=t-t2+1; sam = 0; } continue; } if(b4!=0) { t2=t2+1; sam = sam+1; if(t2==b4) { System.out.println(b3+"号程序结束"); sam = sam-b4; b4=0; } } if((c1==t && arr[2][1]=="r" ||( c1<=t && arr[2][1]=="w" && sam==0 ))&&ci3==0){ System.out.println("开始"+c3+"号程序"); ci3=ci3+1; c4 = c2; } if(arr[2][1]=="w" && ci3==1 ){ t3=t3+1; if(t3==c4) { c4=0; System.out.println(c3+"号程序结束"); arr[2][1]="ch"; t=t-t3+1; sam = 0; } continue; } if(c4!=0) { t3=t3+1; sam = sam+1; if(t3==c4) { System.out.println(c3+"号程序结束"); sam = sam-c4; c4=0; } } if((d1==t && arr[3][1]=="r" ||( d1<=t && arr[3][1]=="w" && sam==0 )) && ci4==0){ System.out.println("开始"+d3+"号程序"); ci4=ci4+1;//为了只输出一次 d4 = d2; } if(arr[3][1]=="w" && ci4==1 ){//ci1表示开始 t4=t4+1; if(t4==d4) { d4=0; System.out.println(d3+"号程序结束"); arr[3][1]="ch"; t=t-t4+1;//把写者踢出 sam = 0; break; } continue; } if(d4!=0) { t4=t4+1; sam = sam+1; if(t4==d4) { System.out.println(d3+"号程序结束"); sam = sam-d4; d4=0; break; } } } System.out.println(); } }