求教读者与写者问题

baar 2013-11-02 12:05:39
正在做一个读者写者问题的作业,要求读者写者公平竞争,我用了队列模拟FIFO的已达到公平竞争,但是在运行时候一直提示队列为空,查了好久,发现我的endReading和endWriting方法在读写完之后均无调用,请问是什么原因?谢谢
下面是我写的程序

这个类是共用堆

import java.util.Queue;


public class Puffer {
private int readerCount;//读者数
private int writerCount;//写者数
private boolean dbReading;//读信号量
private boolean dbWriting;//写信号量
private Queue queue;

public Puffer() {
readerCount=0;
writerCount=0;
dbReading=false;
dbWriting=false;

}
public synchronized int startRead(Reader r){//开始读
while(writerCount>0){
try{
queue.add(r);
System.out.println("reader is waiting");
wait();//等待写者发出notify
}
catch(Exception e){
}
}
readerCount++;
if(readerCount==1){
dbReading=true;
}
return readerCount;
}

public synchronized int endReading(){//结束读
--readerCount;
System.out.println("endReading"+queue.size());

if(readerCount==0&&queue.size()!=0){
dbReading=false;

for(Object o:queue)
{

if(o.toString().equals("Reader"))
{
notifyAll();
queue.remove();
}else
{
notifyAll();
break;
}
}//没有读者

}

//notifyAll();
System.out.println("one reader is done reading. readerCount="+readerCount);
return readerCount;
}
public synchronized void startWriting(Writer w){//开始写
++writerCount;
while(dbReading==true||dbWriting==true){
try{
queue.add(w);
System.out.println("Writer "+writerCount+" is waiting");
wait();//等待读者发出notify
}
catch(Exception e){
}

}
dbWriting =true;
}

public synchronized void endWriting(){//结束写
--writerCount;
System.out.println("endWriting"+queue.size());
if(writerCount==0&&queue.size()!=0){//没有写者
dbWriting=false;

for(Object o:queue)
{

if(o.toString().equals("Reader"))
{
queue.remove();
notifyAll();
}else
{
notifyAll();
break;
}
}
}
//System.out.println("one writer is done writing. writerCount="+writerCount);

//notifyAll();
}

}
...全文
106 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
baar 2013-11-02
  • 打赏
  • 举报
回复
main方法


public class Test {
	public static void main(String args[])
	{
		Puffer p=new Puffer();
		
		  Reader r1=new Reader(1,p);//定义读者r1
		  Reader r2=new Reader(2,p);//定义读者r2
		  Reader r3=new Reader(3,p);
		  Writer w1=new Writer(1,p);//定义写者w1
		  Writer w2=new Writer(2,p);
		 
		  r1.start();
		  w1.start();
		  r2.start();
		  w2.start();
		  r3.start();
		   
	}
}

baar 2013-11-02
  • 打赏
  • 举报
回复
读者类

public class Reader extends Thread{
	private Puffer C;
	 private int readerNum;
	 
	 public Reader(int r,Puffer db) {
	  readerNum=r;
	  C=db;
	 }
	 
	 public void run(){
	  int c;
	  while(true){
		  System.out.println("reader "+readerNum+" wants to read");
		   c=C.startRead(this);
		   System.out.println("reader "+readerNum+" is reading. readerCount="+c);
//		   try {
//				Thread.sleep(5);
//			} catch (InterruptedException e) {
//				// TODO Auto-generated catch block
//				e.printStackTrace();
//			}
		   c=C.endReading();
		   System.out.println("It is reader "+readerNum+" who has done reading. readercount="+c);
		  
	  }
//	  for ( int i = 0 ; i < 5 ; i++)
//	  {
//	   System.out.println("reader "+readerNum+" wants to read");
//	   c=C.startRead(this);  
//	   System.out.println("reader "+readerNum+" is reading. readerCount="+c);
//	   c=C.endReading();
//	   System.out.println("It is reader "+readerNum+" who has done reading. readercount="+c);
//	  
//	  }
	 }

	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return "Reader";
	}
	 
写者类


public class Writer extends Thread{
	private Puffer C;
    private int writerNum;
 public Writer(int w,Puffer db) {
  writerNum=w;
  C=db;
 
 }
 
 public void run(){
  while(true)
	 {
		  System.out.println("Writer "+writerNum+" wants to write");
		   C.startWriting(this);
		 
		   System.out.println("Writer "+writerNum+" is writing");
//		   try {
//				Thread.sleep(50);
//			} catch (InterruptedException e) {
//				// TODO Auto-generated catch block
//				e.printStackTrace();
//			}
		   C.endWriting();
		   System.out.println("It is Writer "+writerNum+" who has done writing .");
	 }
//	  for ( int i = 0 ; i < 5 ; i++)
//	{
//   
//   System.out.println("Writer "+writerNum+" wants to write");
//   C.startWriting(this);
//   System.out.println("Writer "+writerNum+" is writing");
//   C.endWriting();
//   System.out.println("It is Writer "+writerNum+" who has done writing .");
//  
//  }
 
 }
}

Struts2、Hibernate、Spring整合的泛型DAO (本人评价: 代码开发效率提高30% 代码出错率减少70%) 对于大多数开发人员,系统中的每个 DAO 编写几乎相同的代码到目前为止已经成为一种习惯。虽然所有人都将这种重复标识为 “代码味道”,但我们大多数都已经学会忍受它。能不能不写重复的dao 呢 ? 泛型dao,顾名思义就是一个dao可以对多个实体对象进行持久化。当应用中需要使用到上十张表时,DAO的维护变得日益困难,主要表现在这几个方面: 1)dao类的繁多,很多设计都是一个entity对应一个dao (不同的只有类名和方法名) 2)dao接口需要维护的method庞大。 3)业务逻辑改变时,dao需要同时修改两个类文件(接口和实现类) 在本文中,我将为您展示如何避免再三地重复 DAO 代码。 在这里我建议项目最好使用一个共通的DAO,因为这样会为你省去非常多的类,而那些类里的逻辑往往差不多。当然是用共通的DAO你需要对结果转型,转成你需要的bean,但这也比写那么多DAO强多了,你可以放下包袱,只关注你的业务逻辑。 如果你真能只用一个dao解决,那么祝贺你,你得到了一个虚拟数据层(高度抽象的数据接口)。这是一个比dao更高级的存在。 欢迎大家指正 -_- 虚心求教 代码层次: bean-->dao-->service-->action 技术概述:1.继承 继承是利用现有的类创建新类的过程,现有的类称作基类(或父类),创建的新类称作派生类(子类)。继承其实就是自动地共享基类中成员属性和成员方法的机制。引入继承,实现了代码重用; 2.泛型 泛型类型的限定 3.反射 代码概述: bean :Person.java 这个人员类我就不说了 泛型dao接口 :GenericDao 泛型作为DAO的通用接口 CRUD方法 dao接口 : PersonDAO extends GenericDao 可以不写代码,方法已经在父类泛型dao里了,这里为了说明:可扩展添加 findByNameExact()方法 子类的附加方法。 泛型daoimpl :GenericDaoImpl implements GenericDao 必须提供的构造方法,以便创建实例的时候就知道具体实体的类型。 daoimpl :PersonDAOImpl extends GenericDaoImpl implements PersonDAO public PersonDAOImpl() { super(Person.class); } 告诉对哪个类操作,如不需要自定义扩展方法就作有一个构造方法。 泛型Service:GenericService.java 与泛型dao没有区别 Service :PersonService.java 直接继承。 泛型serviceimpl与serviceimpl实现和dao层实现一样。 Action : SavePersonAction直接调用PersonService。 下面是代码 为了演示减少代码量而且直观去掉些方法方便读者自己扩展写出适合自己的代码,这里我只抛砖引玉了。主要介绍这个技术。 本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/zylyueliang/archive/2010/09/17/5890043.aspx
Struts2、Hibernate、Spring整合的泛型DAO (本人评价: 代码开发效率提高30% 代码出错率减少70%) 对于大多数开发人员,系统中的每个 DAO 编写几乎相同的代码到目前为止已经成为一种习惯。虽然所有人都将这种重复标识为 “代码味道”,但我们大多数都已经学会忍受它。能不能不写重复的dao 呢 ? 泛型dao,顾名思义就是一个dao可以对多个实体对象进行持久化。当应用中需要使用到上十张表时,DAO的维护变得日益困难,主要表现在这几个方面: 1)dao类的繁多,很多设计都是一个entity对应一个dao (不同的只有类名和方法名) 2)dao接口需要维护的method庞大。 3)业务逻辑改变时,dao需要同时修改两个类文件(接口和实现类) 在本文中,我将为您展示如何避免再三地重复 DAO 代码。 在这里我建议项目最好使用一个共通的DAO,因为这样会为你省去非常多的类,而那些类里的逻辑往往差不多。当然是用共通的DAO你需要对结果转型,转成你需要的bean,但这也比写那么多DAO强多了,你可以放下包袱,只关注你的业务逻辑。 如果你真能只用一个dao解决,那么祝贺你,你得到了一个虚拟数据层(高度抽象的数据接口)。这是一个比dao更高级的存在。 欢迎大家指正 -_- 虚心求教 代码层次: bean-->dao-->service-->action 技术概述:1.继承 继承是利用现有的类创建新类的过程,现有的类称作基类(或父类),创建的新类称作派生类(子类)。继承其实就是自动地共享基类中成员属性和成员方法的机制。引入继承,实现了代码重用; 2.泛型 泛型类型的限定 3.反射 代码概述: bean :Person.java 这个人员类我就不说了 泛型dao接口 :GenericDao 泛型作为DAO的通用接口 CRUD方法 dao接口 : PersonDAO extends GenericDao 可以不写代码,方法已经在父类泛型dao里了,这里为了说明:可扩展添加 findByNameExact()方法 子类的附加方法。 泛型daoimpl :GenericDaoImpl implements GenericDao 必须提供的构造方法,以便创建实例的时候就知道具体实体的类型。 daoimpl :PersonDAOImpl extends GenericDaoImpl implements PersonDAO public PersonDAOImpl() { super(Person.class); } 告诉对哪个类操作,如不需要自定义扩展方法就作有一个构造方法。 泛型Service:GenericService.java 与泛型dao没有区别 Service :PersonService.java 直接继承。 泛型serviceimpl与serviceimpl实现和dao层实现一样。 Action : SavePersonAction直接调用PersonService。 下面是代码 为了演示减少代码量而且直观去掉些方法方便读者自己扩展写出适合自己的代码,这里我只抛砖引玉了。主要介绍这个技术。 本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/zylyueliang/archive/2010/09/17/5890043.aspx

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧