读者-写者问题
1、读不阻塞其他读
2、读阻塞其他写
3、写阻塞其他读与其他写
问题分为三种:读者优先、写者优先、公平竞争
读者优先:如果当前运行为读线程,则后续的读线程可以不阻塞,直接读
如果当前运行未写线程,则随机选择阻塞的读或写线程,进行执行
写者优先:无论当前为读、写线程运行,优先选择阻塞的写线程
只有当无阻塞的写线程时,阻塞的读线程才获取执行机会
公平竞争:读写线程按照先来后到的顺序(FIFO),依次执行,需要用到队列数据结构
java来解决该问题有很多常用的方法,包括使用 wait()与notify() ,synchronized,使用Semaphore信号量,以及jdk1.5+的其他并发技术,下面以读者优先为例来说明。
1、使用读锁与写锁来解决,这种方法最简单直观,性能也比较好
package com.xx.concurrent.commonUse; import java.util.concurrent.CountDownLatch; public class ReaderAndWriterWithMonitor { //读锁 static Object w = new Object(); //写锁 static Object r = new Object(); //内容 static int data = 0 ; static CountDownLatch latch = new CountDownLatch(150); class Reader extends Thread { int quantity; Reader(int quantity) { this.quantity = quantity; } @Override public void run() { synchronized (w) { while (quantity > 0) { System.out.println(getName() + " is reading ...【data=" + data + "】"); quantity--; } latch.countDown(); } } } class Writer extends Thread { int quantity; Writer(int quantity) { this.quantity = quantity; } @Override public void run() { synchronized (w) { synchronized (r) { while (quantity > 0) { data++; System.out.println(getName() + " is writing...【data=" + data + "】"); quantity--; } latch.countDown(); } } } } public static void main(String[] args) throws InterruptedException { long startTime = System.nanoTime(); ReaderAndWriterWithMonitor demo = new ReaderAndWriterWithMonitor(); for (int i = 0; i < 100; ++i) { demo.new Reader(10).start(); } for (int i = 0; i < 50; ++i) { demo.new Writer(1).start(); } latch.await(); long endTime = System.nanoTime(); System.out.println(endTime - startTime + "ns"); } }
2、使用信号量
package com.xx.concurrent.commonUse; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; public class ReaderAndWriter { static Semaphore mutex = new Semaphore(1); static Semaphore w = new Semaphore(1); static int readcnt = 0 ; static CountDownLatch latch = new CountDownLatch(150); static int data = 0; class Reader extends Thread{ int quantity; Reader(int quantity){ this.quantity = quantity; } @Override public void run(){ while(quantity > 0){ try { mutex.acquire(); readcnt++; if (readcnt == 1) w.acquire(); mutex.release(); //read something System.out.println(getName() + " is reading ...【data=" + data + "】"); mutex.acquire(); readcnt--; if (readcnt == 0) w.release(); mutex.release(); quantity--; } catch (InterruptedException e) { e.printStackTrace(); } } latch.countDown(); } } class Writer extends Thread{ int quantity; Writer(int quantity){ this.quantity = quantity; } @Override public void run(){ while(quantity>0){ try { w.acquire(); data++; System.out.println(getName() + " is writing ...【data=" + data + "】"); w.release(); quantity--; } catch (InterruptedException e) { e.printStackTrace(); } } latch.countDown(); } } public static void main(String[] args) throws InterruptedException { long startTime = System.nanoTime(); ReaderAndWriter demo = new ReaderAndWriter(); ExecutorService service = Executors.newFixedThreadPool(150); for(int i=0; i< 100; ++i){ service.execute(demo.new Reader(10)); } for(int i=0 ; i< 50; ++i){ service.execute(demo.new Writer(1)); } latch.await(); service.shutdown(); long endTime = System.nanoTime(); System.out.println(endTime - startTime + "ns"); } }
3、使用wait和notify方式
package com.xx.concurrent.commonUse; import java.util.concurrent.CountDownLatch; public class ReaderAndWriterWithWaitNotify { static Object w = new Object(); static int readcnt = 0; static int writecnt = 0; static int data = 0; static CountDownLatch latch = new CountDownLatch(150); class Reader extends Thread { int quantity; Reader(int quantity) { this.quantity = quantity; } @Override public void run() { synchronized (w) { try { while (writecnt > 0) { w.wait(); } readcnt++; while (quantity > 0) { System.out.println(getName() + " is reading...【data=" + data + "】" ); quantity--; } } catch (InterruptedException e) { e.printStackTrace(); } readcnt--; w.notify(); latch.countDown(); } } } class Writer extends Thread { int quantity; Writer(int quantity) { this.quantity = quantity; } @Override public void run() { synchronized (w) { while (readcnt > 0 || writecnt > 0) { try { w.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } writecnt++; while (quantity > 0) { data++; System.out.println(getName() + " is writing...【data=" + data + "】" ); quantity--; } writecnt--; w.notify(); latch.countDown(); } } } public static void main(String[] args) throws InterruptedException { long startTime = System.nanoTime(); ReaderAndWriterWithWaitNotify demo = new ReaderAndWriterWithWaitNotify(); for (int i = 0; i < 100; ++i) { demo.new Reader(10).start(); } for (int i = 0; i < 50; ++i) { demo.new Writer(1).start(); } latch.await(); long endTime = System.nanoTime(); System.out.println(endTime - startTime + "ns"); } }
相关推荐
用java实现多线程并发中的读者与写者问题,能够实现多线程对临界资源的同步有序访问。 具体实现为: 给定一个队列A[1-10][1-100000]、元素编号1-10,其中每个元素包含10万个随机数。创建若干个线程,各循环100次;...
(4)可读取样例数据(要求存放在外部文件中),进行读者/写者、进入内存时 间、读写时间的初始化; (5)要求将运行过程用可视化界面动态显示,可随时暂停,查看阅览室读者/ 写者数目、读者等待队列、写者等待队列...
java并发编程pdf文档第二部分:Java并发编程实战.pdf、Java多线程编程核心技术.pdf、实战Java高并发程序设计.pdf
《JAVA并发编程实践》随着多核处理器的普及,使用并发成为构建高性能应用程序的关键。Java 5以及6在开发并发程序中取得了显著的进步,提高了Java虚拟机的性能以及并发类的可伸缩性,并加入了丰富的新并发构建块。在...
本文主要介绍了java高并发写入用户信息到数据库的几种方法,具有很好的参考价值。下面跟着小编一起来看下吧
在Windows环境下,采用系统调用,编程实现读者、写者问题,具体的要求为:一个数据集(如一个文件或记录)为多个并发进程所共享,其中一些进程只要求读该数据集的内容,这些进程称为“读者”,而另一些进程则要求...
主要介绍了Java系统的高并发解决方法,内容十分丰富,在这里分享给大家,需要的朋友可以参考。
读者写者问题实验报告 有代码有流程图 使用PV原语做题
1.3.3 性能问题 1.4 线程无处不在 第一部分 基础知识 第2章 线程安全性 2.1 什么是线程安全性 2.2 原子性 2.2.1 竞态条件 2.2.2 示例:延迟初始化中的竞态条件 2.2.3 复合操作 2.3 加锁机制 2.3.1 内置锁...
《JAVA并发编程实践》随着多核处理器的普及,使用并发成为构建高性能应用程序的关键。Java 5以及6在开发并发程序中取得了显著的进步,提高了Java虚拟机的性能以及并发类的可伸缩性,并加入了丰富的新并发构建块。在...
JAVA并发编程艺术 高清pdf : 1.并发变成的挑战 2. java并发机制的底层实现原理 3. java 内存模型 4. java并发编程基础 5.java中的锁。。。。。。。
Java 5以及6在开发并发程序中取得了显著的进步,提高了Java虚拟机的性能以及并发类的可伸缩性,并加入了丰富的新并发构建块。在《JAVA并发编程实践》中,这 些便利工具的创造者不仅解释了它们究竟如何工作、如何使用...
java并发编程艺术java并发编程艺术java并发编程艺术java并发编程艺术java并发编程艺术
java并发编程实战源码 附有本书所有源码,maven 导入 eclipse或idea
自从java创建以来就已经支持并发的理念,如线程和锁。这篇指南主要是为帮助java多线程开发人员理解并发的核心概念以及如何应用这些理念。本文的主题是关于具有java语言风格的Thread、synchronized、volatile,以及...
Java 并行程序开发的基础, 包括 Java 中 Thread 的基本使用方法等第3章介绍了 JDK 内部对并行程序开发的支持, 主要介绍 JUC (Java.util.concurrent) 中些工具的使用方法、 各自特点及它们的内部实现原理。...
主要总结了:本地内存和线程安全的问题、volatile、synchronized、处理器实现并发的方式、Java实现并发的方式。
Java并发编程的艺术 作者:方腾飞 魏鹏 程晓明 著 丛书名:Java核心技术系列 出版日期 :2015-07-25 ISBN:978-7-111-50824-3 第1章介绍Java并发编程的...第11章介绍几个并发编程的实战,以及排查并发编程造成问题的方法。
如何利用Java开发高性能、高并发Web应用
python几种并发实现方案的性能比较.docx