读者-写者问题的读写操作限制(包括读者优先和写者优先):
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();
}
}