Java并发之读者-写者几种实现
来源:互联网 发布:免费商城系统 php 编辑:程序博客网 时间:2024/04/27 18:12
读者写者经典同步问题的原理算法就不再详细说了!下面给出Java并发写的几种实现,希望支持!
第一种实现:synchronized
DateFile.java
public class DateFile {// readCount表示正在读的人数,初值为0,表示还没有人读。private int readerCount;// doreading表示读信号量,当doreading=true时不能进行写操作。private boolean doreading;// dowriting表示写信号量,当dowriting=ture时不能进行读操作。private boolean dowriting;public DateFile() {readerCount = 0;doreading = false;dowriting = false;}// 线程睡眠,不消耗CPU资源public static void naps() {try {Thread.sleep((int) (4000 * Math.random()));} catch (InterruptedException e) {e.printStackTrace();}}public synchronized int startRead() {// 开始读操作while (dowriting == true) {try {System.out.println(Thread.currentThread().getName()+" is waiting");// 等待写者发出notifywait();} catch (InterruptedException e) {e.printStackTrace();}}System.out.println(Thread.currentThread().getName()+" begin to read!");readerCount++;if (readerCount == 1) {doreading = true;}return readerCount;}public synchronized int endRead() {// 结束读操作--readerCount;if (readerCount == 0) {doreading = false;}notifyAll();System.out.println(Thread.currentThread().getName()+" reading done!");return readerCount;}public synchronized void startWrite() {// 开始写操作while (doreading == true || dowriting == true) {try {System.out.println(Thread.currentThread().getName()+" is waiting");wait();// 等待写者或读者发出notify} catch (InterruptedException e) {e.printStackTrace();}}System.out.println(Thread.currentThread().getName()+" begin to write!");dowriting = true;}public synchronized void endWrite() {// 结束写操作dowriting = false;notifyAll();System.out.println(Thread.currentThread().getName()+" writing done!");}}Reader.java
public class Reader implements Runnable {private int readerNum;private DateFile df;public Reader(int readerNum, DateFile df) {this.readerNum = readerNum;this.df = df;}public void run() {//while (true) {System.out.println("reader " + readerNum + " comes here");df.naps();df.startRead();df.naps();df.endRead();//}}}Writer.java
public class Writer implements Runnable {private DateFile df;private int writerNum;public Writer(int writerNum, DateFile df) {this.df = df;this.writerNum = writerNum;}public void run() {//while (true) {System.out.println("Writer " + writerNum + " comes here");df.naps();df.startWrite();df.naps();df.endWrite();//}}}
WriterReader.java (main方法)
public class WriterReader {public static void main(String[] args) {DateFile df = new DateFile();Reader r1 = new Reader(1, df);Reader r2 = new Reader(2, df);Reader r3 = new Reader(3, df);Reader r4 = new Reader(4, df);Writer w1 = new Writer(1, df);Writer w2 = new Writer(2, df); Writer w3 = new Writer(3, df); new Thread(r1, "读者线程 r1").start(); new Thread(r2, "读者线程r2").start(); new Thread(r3, "读者线程r3").start(); new Thread(r4, "读者线程r4").start(); new Thread(w1, "写者线程w1").start(); new Thread(w2, "写者线程w2").start(); new Thread(w3, "写者线程w3").start();}}
输出结果:
reader 1 comes herereader 2 comes herereader 4 comes hereWriter 2 comes herereader 3 comes hereWriter 1 comes hereWriter 3 comes here读者线程r2 begin to read!读者线程 r1 begin to read!读者线程r2 reading done!写者线程w3 is waiting写者线程w1 is waiting读者线程r4 begin to read!读者线程r3 begin to read!读者线程r4 reading done!写者线程w1 is waiting写者线程w3 is waiting写者线程w2 is waiting读者线程 r1 reading done!写者线程w2 is waiting写者线程w3 is waiting写者线程w1 is waiting读者线程r3 reading done!写者线程w1 begin to write!写者线程w3 is waiting写者线程w2 is waiting写者线程w1 writing done!写者线程w2 begin to write!写者线程w3 is waiting写者线程w2 writing done!写者线程w3 begin to write!写者线程w3 writing done!
第二种实现:Lock和semaphore的实现
Semaphore(信号量)是用来控制同时访问特定资源的线程数量,它通过协调各个线程,以保证合理的使用公共资源。
import java.util.concurrent.Executor;import java.util.concurrent.Executors;import java.util.concurrent.Semaphore;import java.util.concurrent.locks.ReentrantLock;public class Main { private final ReentrantLock lock ; //定义锁 private static int readCount = 0; //读者的数量 private Semaphore writeSemaphore ; //写信号量 public Main() { lock = new ReentrantLock(); writeSemaphore = new Semaphore(1); } public static void main(String[] args) { Main main = new Main(); Executor executors = Executors.newFixedThreadPool(4); executors.execute(main.new Reader()); executors.execute(main.new Reader()); executors.execute(main.new Writer()); executors.execute(main.new Reader()); } class Reader implements Runnable { @Override public void run() { before(); //读操作之前的操作 read(); //读操作 after(); //读操作之后的操作 } public void before() { //读操作之前的操作 final ReentrantLock l = lock; l.lock(); try { if(readCount == 0) { //当有读者时,写者不能进入 writeSemaphore.acquire(1); } readCount += 1; System.out.println("有1位读者进入"); } catch (InterruptedException e) { e.printStackTrace(); } finally { l.unlock(); } } public void read() { //读操作 System.out.println("当前有 " + readCount + " 位读者"); } public void after() { //读操作之后的操作 final ReentrantLock l = lock; l.lock(); try { readCount -= 1; System.out.println("有1位读者离开" ); if(readCount == 0) //当读者为0时,写者才可以进入 writeSemaphore.release(1); } finally { l.unlock(); } } } class Writer implements Runnable { @Override public void run() { final ReentrantLock l = lock; l.lock(); try { try { writeSemaphore.acquire(1); //同时只有一个写者可以进入 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("写者正在写"); writeSemaphore.release(1); } finally { l.unlock(); } } }}
另外:见到一种更好理解的实现方式,用synchronized来实现,原子性地实现信号量的PV操作
class Semaphore{int value;public Semaphore(int v){this.value = v;}public synchronized void p(){value = value-1;if(value<0){try {wait();} catch (InterruptedException e) {e.printStackTrace();}}}public synchronized void v(){value = value+1;if(value<=0){this.notifyAll();}}}
class Reader implements Runnable{int count;Semaphore rmutex;Semaphore wmutex;public Reader(int c,Semaphore r,Semaphore w){this.count = c;this.rmutex = r;this.wmutex = w;}public void run(){while(true){rmutex.p();if(count == 0) wmutex.p();//当第一读进程欲读数据库时,阻止写进程写count++;rmutex.v();System.out.println(count+" begin read data");rmutex.p();count--;System.out.println(count+" finish read data");if(count == 0) wmutex.v();//当最后一个读进程读完数据库时,运行写进程写rmutex.v();}}}class Writer implements Runnable{Semaphore wmutex;public Writer(Semaphore w){this.wmutex = w;}public void run(){while(true){wmutex.p();System.out.println("begin write data");System.out.println("finish write data");wmutex.v();try {Thread.sleep((long) (Math.random()*1000));} catch (InterruptedException e) {e.printStackTrace();}}}}public class ReaderWriter{public static void main(String[] args){int count = 0;Semaphore rmutex = new Semaphore(1);Semaphore wmutex = new Semaphore(1);Reader reader = new Reader(count,rmutex,wmutex);Writer writer = new Writer(wmutex);Thread r = new Thread(reader);Thread r1 = new Thread(reader);Thread w = new Thread(writer);Thread w1 = new Thread(writer);w1.start();r.start();w.start();try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}r1.start();}}
1 0
- Java并发之读者-写者几种实现
- Java并发之读者写者模型
- 图书管理系统之读者信息管理实现
- JAVA多线程实现读者写者问题
- java实现读者-写者问题
- java并发之SynchronousQueue实现原理
- Java并发之synchronized实现原理
- 操作系统内核实验之 读者-写者实现
- 用JAVA实现的第二类读者写者问题
- Java实现生产者消费者问题与读者写者问题
- Java实现生产者消费者问题与读者写者问题
- 读者写者问题之写者优先(java)
- 读者写者问题之写者优先(java)
- 读者写者问题之读者优先
- Java实现多线程并发
- Java并发之生产者-消费者几种实现
- java并发学习之BlockingQueue实现生产者消费者
- 深入理解Java并发之synchronized实现原理
- 使用Servlet实现增删改查的功能
- HDU 4005 边双联通分量
- Python与MySQL联动实例一两则
- CentOS 安装 apache
- 日期格式化 android.text.format.DateFormat
- Java并发之读者-写者几种实现
- Java final String类的详细用法还有特性说明,自己也在学习.
- ArcGIS使用Python脚本工具
- PyGobject(六十五)Gtk.Widget之Gtk.Image
- MYSQL主从配置及读写分离
- Java多线程内存模型
- 蓝牙4.2新增联网、多对多Mesh技术或将取代Zigbee?
- PHP和JAVASCRIPT的混写方法
- java生成简单验证码