1 package写者优先;2
3 importjava.util.Scanner;4
5
6
7 public classMain {8
9 public static voidmain(String[] args) {10 System.out.print("请设置读者数目:");11 Scanner scan=newScanner(System.in);12 int readNum =scan.nextInt();13
14 System.out.print("请设置写者数目:");15 scan=newScanner(System.in);16 int writeNum =scan.nextInt();17
18 System.out.print("请设置循环上限:");19 scan=newScanner(System.in);20 Global.UpBound =scan.nextInt();21
22 scan.close();23
24
25 Reader r[]=newReader[readNum];26 Writer w[]=newWriter[writeNum];27 inti;28 for(i=0;i
49
50
51 }52
53 }54
55 class syn{//PV操作类
56 int count=0;//信号量
57 syn(){}58 syn(int a){count=a;}59 public synchronized void Wait(){ //关键字 synchronized 保证了此操作是一条【原语】
60 count--;61 if(count<0){//等于0 :有一个进程进入了临界区
62 try { //小于0:abs(count)=阻塞的进程数目
63 this.wait();64 } catch(InterruptedException e) {65 e.printStackTrace();66 }67 }68 }69 public synchronized void Signal(){ //关键字 synchronized 保证了此操作是一条【原语】
70 count++;71 if(count<=0){//如果有进程阻塞
72 this.notify();//All
73 }74 }75 }76
77 classGlobal{78 static syn mutex=new syn(1);//控制互斥访问的数据区
79 static syn rmutex=new syn(1);//多个【读者】对readcount进行【互斥】访问
80 static syn wmutex=new syn(1);//多个【写者】对writecount进行【互斥】访问
81 static syn readable=new syn(1);//表示当前是否有写者
82
83 static int dataZone=0; //数据区
84 static int readcount=0; //用于记录读者的数量
85 static int writecount=0; //用于记录读者的数量
86
87 static int data=0;88 static int UpBound=20;89
90 }91
92 class Reader implements Runnable{//读者
93 int ID=0;94 Reader(){}95 Reader(int id){ID=id;}96 public voidrun(){97 while(Global.data<=Global.UpBound){98 Global.readable.Wait();//检测是否存在写者,无写者才能进入99
100 //对readcount进行操作
101 Global.rmutex.Wait();102 if(Global.readcount==0){//这是第一个读者,应该阻止写者的进入
103 Global.mutex.Wait();104 }105 Global.readcount++;//读者数量增减
106 Global.rmutex.Signal();107 //对readcount操作结束
108
109 Global.readable.Signal();//恢复readable
110
111 /*
112 * 进行读操作113 */
114 int readData=Global.dataZone;115 System.out.println("读者"+ID+"读出了数据:"+readData);116 try{117 Thread.sleep(100);118 } catch(InterruptedException e) {119 e.printStackTrace();120 }121 /*
122 * 结束读操作123 */
124
125 //对readcount进行操作
126 Global.rmutex.Wait();127 Global.readcount--;//读者数量减少
128 if(Global.readcount==0){//这是最后一个读者,唤醒写者
129 Global.mutex.Signal();130 }131 Global.rmutex.Signal();132 //对readcount操作结束
133 }134 }135 }136
137 class Writer implements Runnable{//写者
138 int ID=0;139 Writer(){}140 Writer(int id){ID=id;}141 public voidrun(){142 while(Global.data<=Global.UpBound){143 Global.wmutex.Wait();//准备修改writecount
144 if(Global.writecount==0) Global.readable.Wait();//如果是第一个读者,则阻止后续读者进入
145 Global.writecount++;146 Global.wmutex.Signal();//结束对writecount的修改
147
148 Global.mutex.Wait(); //申请对数据区进行访问
149 /*
150 * 进行写操作151 */
152 Global.data++;153 int writeData=Global.data;154 System.out.println("写者"+ID+"写入了数据:"+writeData);155 Global.dataZone=Global.data;156 try{157 Thread.sleep(10);158 } catch(InterruptedException e) {159 //TODO Auto-generated catch block
160 e.printStackTrace();161 }162 /*
163 * 结束写操作164 */
165 Global.mutex.Signal(); //释放数据区,允许其他进程读写
166
167 Global.wmutex.Wait();//准备修改writecount
168 Global.writecount--;169 if(Global.writecount==0) Global.readable.Signal();//如果是最后一个写者,唤醒读者
170 Global.wmutex.Signal();//结束对writecount的修改
171 }172 }173 }