1. 程式人生 > >Java實現讀者寫者問題(讀者優先)(程序同步)

Java實現讀者寫者問題(讀者優先)(程序同步)

讀者-寫者問題的讀寫操作限制(包括讀者優先和寫者優先):

 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();
	}
}