`

java 并发(4) 读者写者问题的几种实现方法及性能比较

    博客分类:
  • Java
 
阅读更多

读者-写者问题

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并发编程实战pdf,Java

    《Java并发编程实战》是Java并发编程领域的一本经典著作,它深入浅出地介绍了如何在Java平台上进行高效的多线程编程。这本书的源码提供了丰富的示例,可以帮助读者更好地理解书中的理论知识并将其应用到实际项目中。...

    解决读者——写者问题---操作系统课程设计

    总的来说,这个课程设计涵盖了操作系统中的一个重要概念,即并发控制,通过解决读者-写者问题,学生能够深入理解多线程环境下的同步与互斥,并掌握如何运用同步原语来解决这类问题。同时,通过编写和调试代码,也能...

    读者/写者的同步互斥问题

    在bd系统内核实验-读者-写者问题源代码中,可能就包含了一些具体的实现方式,如采用自旋锁(Spinlock)或者使用高级的并发原语来优化性能。 总之,读者/写者问题展示了在多线程环境下如何有效控制对共享资源的访问...

    实战Java高并发程序设计(高清版)

    5. **J.U.C框架**:Java并发 utilities (J.U.C) 框架是Java并发编程的重要组成部分,书中会介绍如何利用这个框架来提升并发性能和代码的可读性。 6. **性能调优**:在高并发场景下,性能优化是必不可少的。可能涵盖...

    ( java并发编程.zip )文字版 电子书 高清版

    4. **并发集合**:Java并发集合库(java.util.concurrent包)提供了一系列线程安全的数据结构,如ConcurrentHashMap、CopyOnWriteArrayList、BlockingQueue等,它们在并发环境下具有高性能和高安全性。 5. **原子...

    java并发编程实践中文版和英文版

    5. **并发设计模式**:书中有专门章节介绍了几种常见的并发设计模式,如生产者消费者模式、工作窃取模式、线程池等,以及如何避免和解决并发编程中常见的问题,如死锁、活锁和饥饿。 6. **并发性能优化**:在性能...

    《java并发编程实践》

    《Java并发编程实践》这本书是Java开发者深入了解并发编程的重要参考资料,尤其对于想要提升在多线程环境下编程技能的程序员来说,它提供了丰富的实践经验和深入的理论解析。在Java的世界里,多线程是构建高性能、高...

    《Java并发编程实战》PDF版本下载.txt

    《Java并发编程实战》一书系统地介绍了Java并发编程的基础知识和高级特性,并通过大量实战案例帮助读者理解和掌握Java并发编程技术。通过学习本书,开发者可以更好地利用多核处理器的优势,提高应用程序的性能和响应...

    《Java并发编程艺术》高清带目录中文版

    阅读《Java并发编程艺术》,读者不仅可以掌握Java并发编程的基本理论,还能学习到如何在实际项目中应用这些知识,提升代码的并发性能和可维护性。这是一本对Java开发者非常有价值的参考资料,尤其对于需要处理高并发...

    Java并发编程源码

    7. **并发模式**:包括生产者消费者模型、读者写者模式、工作窃取算法等,这些模式是解决并发问题的常用策略。 8. **JVM内存模型**:Java内存模型(JMM)定义了线程如何访问共享变量,以及如何确保内存的一致性。 ...

    Java 并发编程实战pdf + 随书源码 (书高清版,带超详细书签目录)

    《Java并发编程实战》是一本深入探讨Java平台上的并发编程技术的专业书籍,旨在帮助开发者理解和掌握多线程环境下的高效编程方法。这本书结合了理论与实践,提供了丰富的示例代码和详细的书签目录,便于读者查找和...

    Java高并发程序设计

    本书还详细讲解了几种常用的并发编程模式,如: - **生产者-消费者模式**:通过阻塞队列实现的典型多线程协作模式。 - **读写锁**:通过区分读操作和写操作来提高并发性能。 - **屏障模式**:利用`CyclicBarrier`和...

    java并发编程实践

    《Java并发编程实践》这本书是Java开发者深入了解并发编程的重要资源,尤其对于初学者来说,它提供了许多实用的例子,帮助读者逐步掌握并发编程的核心概念和技术。并发编程是现代多核处理器环境下提升程序性能的关键...

    java并发编程实战源码,java并发编程实战pdf,Java源码.zip

    《Java并发编程实战》是一本深入探讨Java多线程和并发编程的经典著作,它由Brian Goetz、Tim Peierls、Joshua Bloch、David Holmes和Doug Lea合著,旨在帮助开发者理解和掌握Java并发的核心概念和技术。这本书的源码...

    Java并发编程的艺术&源码

    《Java并发编程的艺术》是一本深入探讨Java平台上的并发编程技术的专业书籍,它结合理论与实践,详细解析了Java并发编程中的各种概念、工具和最佳实践。这本书的源码提供了丰富的示例,帮助读者更好地理解和应用书中...

    Java并发编程实践.绝版书籍

    在Java并发编程中,有几个核心概念是必须掌握的: 1. **线程**:线程是程序执行的最小单元,每个线程都拥有自己的程序计数器、系统栈和局部变量。Java通过`Thread`类提供对线程的支持,可以创建并启动新的线程来...

    一本经典的多线程书籍 Java并发编程 设计原则与模式 第二版 (英文原版)

    5. **并发设计模式**:书中详细阐述了几种常见的并发设计模式,如生产者消费者模式、读写锁模式、双检锁模式(DCL)等,这些都是解决特定并发问题的有效策略。 6. **线程池**:Java的Executor框架提供了线程池管理,...

    java写的java虚拟机

    通过阅读这篇博文,读者可能会了解到作者如何使用Java来实现这些功能,以及他们在实现过程中遇到的问题和解决方案。这将对理解JVM的工作原理有极大的帮助,同时也可能提供一种学习和研究JVM的新途径。对于想要深入...

    对java的BitSet的多线程并发的探索

    2. **使用Lock**:Java并发库中的ReentrantLock或LockSupport也可以用来控制并发访问,提供更细粒度的锁,提高性能。 3. **AtomicIntegerArray或AtomicLongArray**:虽然BitSet本身不是线程安全的,但我们可以借助...

Global site tag (gtag.js) - Google Analytics