读写者问题-java实现

28 篇文章 2 订阅
   读者—写者问题(Readers-Writers problem)也是一个经典的并发程序设计问题,是经常出现的一种同步问题。计算机系统中的数据(文件、记录)常被多个进程共享,但其中某些进程可能只要求读数据(称为读者Reader);另一些进程则要求修改数据(称为写者Writer)。就共享数据而言,Reader和Writer是两组并发进程共享一组数据区,要求:
(1)允许多个读者同时执行读操作;
(2)不允许读者、写者同时操作;

(3)不允许多个写者同时操作。

实现的原理:

     单纯使用信号量不能解决读者与写者问题,必须引入计数器readcount对读进程计数;readcountsemophore 是用于对计数器readcount 操作的互斥信号量,之所以引入该信号量是为了保证原子操作(其实java中有关键字synchronized可以实现对块的原子操作,保证只有一个线程来操作该块,其实这个关键字就是封装了信号量)。write表示是否允许写的信号量;于是读者优先的程序设计原理如下:

读者:

  while(true)

      P(rcs);

     if(rc==0)

    {

          rc++;

          P(write);

    }

   V(rcs);

//读数据

  P(rcs)

   rc--;

    if(rc==0)

         V(write);

  V(rcs)

写者:

while(true)

{

      P(write);

      //写写写

      V(write);

}

java 实现:

          读者:

import java.util.Random;
import java.util.concurrent.Semaphore;

public class ReadThread extends Thread
{
	public int id;// 读者ID
	//public int readCount;// 读者数量
	public Semaphore readCountSemaphore;// 读者数量信号量
	public Semaphore writeSemaphore;// 写者信号量

	public ReadThread(int id,  Semaphore semaphore,
			Semaphore semaphore2)
	{
		this.id = id;
		this.readCount = rcount;
		this.readCountSemaphore = semaphore;
		this.writeSemaphore=semaphore2;
		this.start();// 开始读
	}
//读者优先
	public void run()
	{
		try
		{
			//没人在写
			if(writeSemaphore.availablePermits()>0)//可以读
				System.out.println("读者"+id+"可以读...");
			else {
				System.out.println("有写者在写操作,读者"+id+"等待读...");
			}
			// 等待着读
			readCountSemaphore.acquire();
			if (<span style="font-family: Arial, Helvetica, sans-serif;">ReadAndWrite.</span>readCount == 0)//如果第一个读者,那么要考虑是否有写者,没有写者,直接读,有写者,等待写者
			{
                               //此时不能写
				<span style="font-family: Arial, Helvetica, sans-serif;">ReadAndWrite.</span><span style="font-family: Arial, Helvetica, sans-serif;">readCount</span><span style="font-family: Arial, Helvetica, sans-serif;">++;// 已经具备读的条件了,读者数量加1</span>
				writeSemaphore.acquire();
			}
			readCountSemaphore.release();
			/**********************************/
			
			//此刻才可以允许其他读者读数据
			
			/**********************************/
			readCountSemaphore.acquire();
			//可以读了
			System.out.println("读者"+id+"我正在读哦...");
			Thread.sleep((long) (new Random().nextFloat()*2000));
			System.out.println("读者"+id+"读完了...");
			//读完了,读者数量减少1
			ReadAndrWrite.readCount--;
			if(<span style="font-family: Arial, Helvetica, sans-serif;">ReadAndrWrite.</span><span style="font-family: Arial, Helvetica, sans-serif;">readCount==0)//没有读者了,可以写了</span>
			{
				writeSemaphore.release();
			}
			readCountSemaphore.release();//释放读者信号量
			
		}
		catch (InterruptedException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

写者:

import java.util.Random;
import java.util.concurrent.Semaphore;

public class WriteThread extends Thread
{
   public int id;//编号
   public Semaphore writeSemaphore;//写者信号量
   public WriteThread(int id,Semaphore semaphore)
   {
	   this.id=id;
	   this.writeSemaphore=semaphore;
	   this.start();
   }
   public void run()
   {
	   try
	{
		 if(writeSemaphore.availablePermits()>0)
		 {
			 System.out.println("写者"+this.id+"可以写");
		 }
		 else
			 System.out.println("写者"+this.id+"不可以写");		 
		writeSemaphore.acquire();
		System.out.println("写者"+this.id+"正在写...");
		Thread.sleep((long) (new Random().nextFloat()*2000));
		System.out.println("写者"+this.id+"写完了...");
		writeSemaphore.release();
	}
	catch (InterruptedException e)
	{
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
   }
}

主程序:

public class ReadAndWrite
{
	public static final int count=10;//读者写者的数量
	public static 	int readCount=0;

	/**
	 * @param args
	 */
	public static void main(String[] args)
	{
		// TODO Auto-generated method stub
		Semaphore readCountSemaphore=new Semaphore(1);
		Semaphore writeSemaphore=new Semaphore(1);
        for(int i=0;i<count;i++)
        {
        	//随机生成读者和写者
        	if(new Random().nextBoolean())//假设是读者
        		new ReadThread(i, readCountSemaphore, writeSemaphore);
        	else {
				new WriteThread(i, writeSemaphore);
			}
        }
	}

}


 

运行效果:

 

      
  • 4
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值