java实现读者-写者问题
来源:互联网 发布:linux ls查看文件大小 编辑:程序博客网 时间:2024/05/01 04:24
问题背景:一个数据文件或记录,可以被多个进程或者线程共享,其中不同的读进程可以并发的访问该临界资源,读和写进程或者线程,不能并发的对该临界资源进行操作,否则造成脏读和脏写,写和写进程之间也是互斥的。而我们今天的读者和写者模式 也称为读写锁,不过这里以信号量的方式进行互斥操作,就可以解决这个问题。
下面来看代码
import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Semaphore;public class RWTest { //创建一个用于记录正在读的读进程数 static int readCount=0; //创建一个读写线程共享的临界资源 static int sse=0; public static void main(String[] args) { //创建一个线程池 ExecutorService es=Executors.newFixedThreadPool(10); //创建一个读写互斥的信号量 final Semaphore wmutex=new Semaphore(1,true); //创建一个用于读进程间的修改临界资源readCount的互斥信号量 final Semaphore rmutex=new Semaphore(1,true); //创建4个读进程 for(int i=0;i<4;i++){ es.execute(new Runnable(){ @Override public void run() { while(!Thread.interrupted()){ try { //获取可以修改readCount的互斥信号量 rmutex.acquire(); //当readCount==0时说明,不存在读线程获得读写的互斥信号量,该信号量只对写线程操作互斥,对读线程不互斥 if(readCount==0){ //获取可以进行IO操作的的互斥信号 wmutex.acquire(); } readCount++; //释放信号量 rmutex.release(); //进行IO读操作 //这里我为了简单明了直接打印 System.out.println(Thread.currentThread().getId()+"正在进行读操作。。。。。。。。"); Thread.sleep(100); System.out.println("读取的数据为"+sse); //获取可以修改readCount的互斥信号量 rmutex.acquire(); readCount--; //释放信号量 rmutex.release(); //当readCount==0时说明,所有读线程不再对共享资源进行操作了,则释放互斥信号量 if(readCount==0) //释放信号量 wmutex.release(); //将cpu调度权让给其他读线程,但操作不一定成功 Thread.yield(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }); } //创建3个写线程 for(int i=0;i<3;i++){ es.execute(new Runnable(){ @Override public void run() { while(!Thread.interrupted()){ try { //获取可以进行IO操作的互斥信号量,防止其他读写线程对临界资源进行操作,如果获取不到,则等待 wmutex.acquire(); //进行IO 写操作 //同样便于简单明了,这里只输出打印 System.out.println(Thread.currentThread().getId()+"正在进行写操作........."); //修改临界资源的值 sse++; //模拟IO操作所需时间 Thread.sleep(1000); System.out.println("数据修改成功"); //释放信号量,让其他的读或写线程可以竞争 wmutex.release(); //将cpu的调度权让给其他写线程,但操作不一定成功 Thread.yield(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }); } }}
结果分析:
我们代码中的无论读或写都不是原子操作的。
有上图可以看出读进程之间是不互斥的,可以并发访问。
有上图可以看出,读进程和写进程之间是互斥的,写进程和写进程之间也是互斥的。
阅读全文
0 0
- JAVA多线程实现读者写者问题
- java实现读者-写者问题
- java 读者写者问题
- Java实现生产者消费者问题与读者写者问题
- Java实现生产者消费者问题与读者写者问题
- 用JAVA实现的第二类读者写者问题
- 有名信号量实现读者-写者问题(读者优先)
- Java 多线性读者写者问题
- Java 多线程读者写者问题
- 读者写者问题(Java多线程)
- 读者写者问题
- 读者写者问题
- 读者-写者问题
- 读者写者问题
- 读者写者问题
- 读者-写者问题
- 读者-写者问题
- 读者-写者问题
- 微信公众号开发,微信支付功能开发(网页JSAPI调用)
- 2016年4月~2017年7月 创业经验总结
- 编译caffe报错:make: *** [runtest] 错误 134
- databinding的一个奇葩问题
- 已解决:序列nocache导致的log file sync等待事件
- java实现读者-写者问题
- 在centos7下编译安装memcached
- 关于面试题中结构体内存对齐计算总结
- 563. Binary Tree Tilt
- linux awk命令详解
- 《Unity 3D游戏客户端基础框架》概述
- B-tree与Mysql
- 玲珑杯round18(数论)
- 秒杀多线程第三篇 原子操作 Interlocked系列函数