`

java并发 locks包:ReentrantReadWriteLock(三)

 
阅读更多

 

在使用某些种类的 Collection 时,可以使用 ReentrantReadWriteLock 来提高并发性。通常,在预期 collection 很大,读取者线程访问它的次数多于写入者线程,并且 entail 操作的开销高于同步开销时,这很值得一试。例如,以下是一个使用 TreeMap 的类,预期它很大,并且能被同时访问

 

代码实例:

 

import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 读写锁的使用
 *
 */
public class ReentrantReadWriteLockMap<T> {
	
	private final Map<String,T> treeMap=new TreeMap<String,T>();
	
	/** 公平策略的读写锁 */
	private final ReentrantReadWriteLock rwl=new ReentrantReadWriteLock(true);
	
	private final Lock rl=rwl.readLock();
	
	private final Lock wl=rwl.writeLock();
	
	
	
	public T get(String key){
		
		rl.lock();
		try{
			return treeMap.get(key);
		}finally{
			rl.unlock();
		}
	}
	
	
	public String[] allKeys() {
		rl.lock();
		try{
			return (String[]) treeMap.keySet().toArray();
		}finally{
			rl.unlock();
		}
	}
	
	
	public T put(String key ,T value){
		wl.lock();
		try{
			return treeMap.put(key, value);
		}finally{
			wl.unlock();
		}
		
	}
	
	
	public void clear(){
		wl.lock();
		try{
			treeMap.clear();
		}finally{
			wl.unlock();
		}
	}
	

	public static void main(String[] args) {

		final ReentrantReadWriteLockMap<String> map=new ReentrantReadWriteLockMap<String>();
		
		new Thread(){
			public void run(){
				for(int i=1;i<=10000;i++){
					try {
						Thread.sleep(10);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					map.put("key:"+i, Integer.toString(i));
				}
			}
		}.start();
		
		
		new Thread(){
			public void run(){
				for(int i=1;i<=10000;i++){
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					String t=map.get("key:"+i);
					if(t==null||"".equals(t)){
						
					}
					
					System.out.println(map.get("key:"+i));
				}
			}
		}.start();
	}

}

 

允许从写入锁降级为读取锁,其实现方式是:先获取写入锁,然后获取读取锁,最后释放写入锁。但是,从读取锁升级到写入锁是不可能的。 

 

代码实例:

/**
  * 摘抄自JDK文档的伪代码
  */
class CachedData {
   Object data;
   volatile boolean cacheValid;
   ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();

   void processCachedData() {
     rwl.readLock().lock();
     if (!cacheValid) {
        // Must release read lock before acquiring write lock
        rwl.readLock().unlock();
        rwl.writeLock().lock();
        // Recheck state because another thread might have acquired
        //   write lock and changed state before we did.
        if (!cacheValid) {
          data = ...
          cacheValid = true;
        }
        // Downgrade by acquiring read lock before releasing write lock
        rwl.readLock().lock();
        rwl.writeLock().unlock(); // Unlock write, still hold read
     }

     use(data);
     rwl.readLock().unlock();
   }
 }

 

 

 

分享到:
评论

相关推荐

    Java并发包源码分析(JDK1.8)

    Java并发包源码分析(JDK1.8):囊括了java.util.concurrent包中大部分类的源码分析,其中涉及automic包,locks包(AbstractQueuedSynchronizer、ReentrantLock、ReentrantReadWriteLock、LockSupport等),queue...

    [中文]Java并发编程的艺术pdf

    《Java并发编程的艺术》这本书是Java开发者深入理解并发编程的重要参考。并发编程是现代多核处理器环境下不可或缺的技术,它能够充分利用系统资源,提高程序的执行效率。以下将详细阐述书中涉及的一些关键知识点。 ...

    Java并发编程学习笔记

    Java并发编程是Java开发中必不可少的一部分,涉及到多线程、同步机制、线程池以及并发工具类等多个核心知识点。以下是对这些主题的详细说明: 1. **线程安全与锁 Synchronized 底层实现原理**: 线程安全是指在多...

    Java并发编程进阶练习代码

    Java提供了多种锁机制,包括内置锁(synchronized)、显式锁(java.util.concurrent.locks包下的Lock接口及其实现)以及读写锁(ReentrantReadWriteLock)。理解并熟练使用这些锁能帮助你控制线程的执行顺序,解决竞...

    实现Java高并发隔离 模拟

    3. **读写锁(ReentrantReadWriteLock)**:当读操作远多于写操作时,`java.util.concurrent.locks.ReentrantReadWriteLock`比`synchronized`更高效。读操作可并发执行,而写操作互斥。 4. **信号量(Semaphore)**...

    Java并发编程实践

    《Java并发编程实践》这本书深入探讨了Java平台上的并发编程技术,是Java开发者提升多线程编程能力的重要参考资料。在Java编程中,并发是提高系统性能、实现高并发处理的关键技术,尤其在如今多核处理器普及的时代,...

    Java的两种读写锁介绍

    在Java并发编程中,读写锁是用于优化多线程访问共享资源的一种机制,它可以提高对数据的并发访问效率。本文将深入探讨Java中的两种读写锁:ReentrantReadWriteLock和StampedLock,并分析它们的工作原理、特点以及...

    java并发工具类

    Java并发工具类是Java平台提供的一系列用于处理多线程并发问题的类和接口,它们在`java.util.concurrent`包中。并发问题主要包括资源竞争、死锁、活锁以及饥饿等,合理使用并发工具可以有效地提高程序的并发性能并...

    java并发源码分析之实战编程

    锁机制是Java并发中的重要工具,包括内置锁(synchronized关键字)和显式锁(java.util.concurrent.locks包下的ReentrantLock、ReentrantReadWriteLock等)。内置锁简洁易用,但功能有限;显式锁则提供了更灵活的...

    Java 多线程与并发(12-26)-JUC锁- ReentrantReadWriteLock详解.pdf

    在Java多线程并发编程中,ReentrantReadWriteLock(可重入读写锁)是一个重要的同步工具,它属于Java并发包(java.util.concurrent.locks)中的一个类。这个锁提供了比标准的synchronized关键字更细粒度的控制,允许...

    Java多线程 ReentrantReadWriteLock原理及实例详解

    Java的ReentrantReadWriteLock是Java并发包`java.util.concurrent.locks`中的一个重要工具,它提供了一种更细粒度的锁定机制,相比普通的独占锁(如ReentrantLock)在某些场景下能显著提高程序的并发性能。...

    Java并发编程实践-电子书-07章.pdf

    ### Java并发编程实践-电子书-07章:显示锁详解 #### 一、章节概述 本章节聚焦于Java中的显示锁(Explicit Locks),尤其是`ReentrantLock`的使用和高级特性。显示锁提供了比Java自带的`synchronized`关键字更为...

    java concurrent in practive

    另外,`java.util.concurrent.locks`包提供了可重入锁`ReentrantLock`和读写锁`ReentrantReadWriteLock`,它们比`synchronized`更灵活,允许更细粒度的锁控制。 死锁、活锁和饥饿是并发编程中常见的问题,书中会...

    JAVA_并发编程面试专题15道.pdf

    Java 并发编程是 Java 开发中的...以上知识点涵盖了Java并发编程的核心概念,如线程同步、锁机制、并发容器、死锁与竞态条件等,这些都是面试中常见的问题,深入理解这些概念对于成为一名优秀的Java开发者至关重要。

    java常用锁使用demo工程

    这个“java常用锁使用demo工程”应该包含了上述知识点的实例,通过实际操作和调试这些代码,开发者可以深入理解Java并发编程的核心概念,并学会在实际项目中有效地应用锁机制,提升多线程环境下的程序性能和稳定性。

    《Java Concurrency in Practice》代码示例

    《Java Concurrency in Practice》是Java并发编程领域的一本经典著作,由Brian Goetz、Tim Peierls、Joshua Bloch、David Holmes和Doug Lea合著。这本书深入浅出地探讨了Java平台上的多线程和并发编程,提供了丰富的...

    java 读写锁代码

    Java 读写锁是Java并发编程中的一种重要机制,它为多线程环境下的数据访问提供了更为精细的控制。在Java的`java.util.concurrent.locks`包中,`ReentrantReadWriteLock`类实现了读写锁的功能。这个锁允许多个读取者...

    互联网高频Java后端面试题20道(适合1~3年)V1.0.82.docx

    2. **ReentrantLock**:可重入锁,它是 java.util.concurrent.locks 包下的一个类,提供了与 synchronized 类似的功能,但更加强大和灵活。ReentrantLock 支持公平锁和非公平锁,并且可以实现锁的尝试获取、定时等待...

    Java面试题并发部分.docx

    在Java并发编程中,面试时常会涉及到一系列的关键概念和技术,以下是对这些知识点的详细解释: 1. **死锁**:死锁是指两个或多个线程互相等待对方释放资源,导致它们都无法继续执行的情况。比如线程A持有资源1并...

Global site tag (gtag.js) - Google Analytics