经典同步互斥问题之读者—写者问题

来源:互联网 发布:淘宝分享怎么查看 编辑:程序博客网 时间:2024/05/17 22:26

问题描述:


第一次看到这个问题的时候,感觉很简单,不屑于看,然而当我上手敲代码的时候就懵逼了:道理很清楚很明白,可是代码实现确不是那么简单,想了一天都没想通。第二天参考了一篇文章,才理清思路。贴上我认为最简短的而且还能达到题目要求解决所给问题的代码:

//Test.javaimport java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.Scanner;public class Test {/** * @param args * 创建了五个线程(四个读,一个写),让它们自己竞争,所以每次运行代码结果是不一样滴。 */public static void main(String[] args) {// TODO Auto-generated method stubTicket ticket=new Ticket(100);Mythread mythread1=new Mythread(ticket,"R");Mythread mythread2=new Mythread(ticket,"R");Mythread mythread3=new Mythread(ticket,"W");Mythread mythread4=new Mythread(ticket,"R");Mythread mythread5=new Mythread(ticket,"R");mythread1.start();mythread3.start();mythread2.start();mythread4.start();mythread5.start();}}
//Ticket.javapublic class Ticket {private int num;//标记当前是否有写线程正在执行private Boolean write=false;Ticket(){}Ticket(int n){this.num=n;}public int read(){System.out.println("====================================");System.out.println("我是读,我来了");while(true){if(this.write){//如果有写线程正在执行System.out.println("wait...");try{wait();}catch (Exception e) {}}else{System.out.println("剩余票数:"+this.num);break;}}System.out.println("我读完了");System.out.println("====================================");return this.num;}public synchronized void write(){this.write=true;//进入写线程,首先改变标记System.out.println("====================================");System.out.println("我是写,我来了");this.num--;//try {//Thread.sleep(10);//} catch (InterruptedException e) {//// TODO Auto-generated catch block//e.printStackTrace();//}  System.out.println("修改后的票数:"+this.num);System.out.println("我写完了");System.out.println("====================================");this.write=false;//退出写线程,恢复标记} }
//Mythread.javapublic class Mythread extends Thread{Ticket ticket;public String flag;//标记该线程是读或写Mythread(Ticket tic,String ch){this.ticket=tic;this.flag=ch;}@Overridepublic void run() {// TODO Auto-generated method stubif("W".equals(this.flag)){this.ticket.write();}else if("R".equals(this.flag)){this.ticket.read();}}}

核心代码在Ticket.java类,也不多,哈哈。。


可以看到:当有写操作的时候,无论当前的读操作是否完成,都得进入阻塞,等待写操作完成后,再进行读操作。





阅读全文
0 0
原创粉丝点击