读者-写者问题
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并发编程实战》是Java并发编程领域的一本经典著作,它深入浅出地介绍了如何在Java平台上进行高效的多线程编程。这本书的源码提供了丰富的示例,可以帮助读者更好地理解书中的理论知识并将其应用到实际项目中。...
总的来说,这个课程设计涵盖了操作系统中的一个重要概念,即并发控制,通过解决读者-写者问题,学生能够深入理解多线程环境下的同步与互斥,并掌握如何运用同步原语来解决这类问题。同时,通过编写和调试代码,也能...
在bd系统内核实验-读者-写者问题源代码中,可能就包含了一些具体的实现方式,如采用自旋锁(Spinlock)或者使用高级的并发原语来优化性能。 总之,读者/写者问题展示了在多线程环境下如何有效控制对共享资源的访问...
5. **J.U.C框架**:Java并发 utilities (J.U.C) 框架是Java并发编程的重要组成部分,书中会介绍如何利用这个框架来提升并发性能和代码的可读性。 6. **性能调优**:在高并发场景下,性能优化是必不可少的。可能涵盖...
4. **并发集合**:Java并发集合库(java.util.concurrent包)提供了一系列线程安全的数据结构,如ConcurrentHashMap、CopyOnWriteArrayList、BlockingQueue等,它们在并发环境下具有高性能和高安全性。 5. **原子...
5. **并发设计模式**:书中有专门章节介绍了几种常见的并发设计模式,如生产者消费者模式、工作窃取模式、线程池等,以及如何避免和解决并发编程中常见的问题,如死锁、活锁和饥饿。 6. **并发性能优化**:在性能...
《Java并发编程实践》这本书是Java开发者深入了解并发编程的重要参考资料,尤其对于想要提升在多线程环境下编程技能的程序员来说,它提供了丰富的实践经验和深入的理论解析。在Java的世界里,多线程是构建高性能、高...
《Java并发编程实战》一书系统地介绍了Java并发编程的基础知识和高级特性,并通过大量实战案例帮助读者理解和掌握Java并发编程技术。通过学习本书,开发者可以更好地利用多核处理器的优势,提高应用程序的性能和响应...
阅读《Java并发编程艺术》,读者不仅可以掌握Java并发编程的基本理论,还能学习到如何在实际项目中应用这些知识,提升代码的并发性能和可维护性。这是一本对Java开发者非常有价值的参考资料,尤其对于需要处理高并发...
7. **并发模式**:包括生产者消费者模型、读者写者模式、工作窃取算法等,这些模式是解决并发问题的常用策略。 8. **JVM内存模型**:Java内存模型(JMM)定义了线程如何访问共享变量,以及如何确保内存的一致性。 ...
《Java并发编程实战》是一本深入探讨Java平台上的并发编程技术的专业书籍,旨在帮助开发者理解和掌握多线程环境下的高效编程方法。这本书结合了理论与实践,提供了丰富的示例代码和详细的书签目录,便于读者查找和...
本书还详细讲解了几种常用的并发编程模式,如: - **生产者-消费者模式**:通过阻塞队列实现的典型多线程协作模式。 - **读写锁**:通过区分读操作和写操作来提高并发性能。 - **屏障模式**:利用`CyclicBarrier`和...
《Java并发编程实践》这本书是Java开发者深入了解并发编程的重要资源,尤其对于初学者来说,它提供了许多实用的例子,帮助读者逐步掌握并发编程的核心概念和技术。并发编程是现代多核处理器环境下提升程序性能的关键...
《Java并发编程实战》是一本深入探讨Java多线程和并发编程的经典著作,它由Brian Goetz、Tim Peierls、Joshua Bloch、David Holmes和Doug Lea合著,旨在帮助开发者理解和掌握Java并发的核心概念和技术。这本书的源码...
《Java并发编程的艺术》是一本深入探讨Java平台上的并发编程技术的专业书籍,它结合理论与实践,详细解析了Java并发编程中的各种概念、工具和最佳实践。这本书的源码提供了丰富的示例,帮助读者更好地理解和应用书中...
在Java并发编程中,有几个核心概念是必须掌握的: 1. **线程**:线程是程序执行的最小单元,每个线程都拥有自己的程序计数器、系统栈和局部变量。Java通过`Thread`类提供对线程的支持,可以创建并启动新的线程来...
5. **并发设计模式**:书中详细阐述了几种常见的并发设计模式,如生产者消费者模式、读写锁模式、双检锁模式(DCL)等,这些都是解决特定并发问题的有效策略。 6. **线程池**:Java的Executor框架提供了线程池管理,...
通过阅读这篇博文,读者可能会了解到作者如何使用Java来实现这些功能,以及他们在实现过程中遇到的问题和解决方案。这将对理解JVM的工作原理有极大的帮助,同时也可能提供一种学习和研究JVM的新途径。对于想要深入...
2. **使用Lock**:Java并发库中的ReentrantLock或LockSupport也可以用来控制并发访问,提供更细粒度的锁,提高性能。 3. **AtomicIntegerArray或AtomicLongArray**:虽然BitSet本身不是线程安全的,但我们可以借助...