`
uule
  • 浏览: 6337765 次
  • 性别: Icon_minigender_1
  • 来自: 一片神奇的土地
社区版块
存档分类
最新评论

利用ReentrantReadWriteLock实现缓存系统

 
阅读更多

 

首先解释下缓存系统:

           在程序运行过程中,有些数据我们不会经常修改,例如数据库中性别字段,但是我们却经常使用,如果每次都从数据库中获取,那么将会降低程序性能。那么我们可以在内存中分配一个区域专门存放我们第一次从数据库中拿出的数据。思路如下:我们使用Map来充当我们的缓存区域,当使用性别值时,可以先看看map中是否有值,如果有那么拿出来,如果没有那么查询数据库,并为map赋值。

 

           思路如上,但是我们要考虑多线程的问题,如果多个程序同时使用该缓存系统,有的读,有的写,那么很有可能在某一时刻,一个线程为map赋值了,但是另一个线程或多个线程会重复为map赋值。这就是多线程的并发问题,如何解决,我们采用Java5的读写锁来实现。ReentrantReadWriteLock(详细解释参见Java5 API)。读锁和写锁同步,读的时候不允许写,写的时候不允许读,可以同时读。

 

 

import java.util.HashMap;  
import java.util.Map;  
import java.util.concurrent.locks.ReentrantReadWriteLock;  
  
public class CacheDemo {  
  
    private static Map<String, Object> cacheData = new HashMap<String, Object>();//构造缓存对象  
    private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();//构造读写锁  

    public static void main(String[] args) {  
                    
    }  
  
      
    public Object getData(String key){  
        Object value = null;  
        try{  
            rwl.readLock().lock();//当线程开始读时,首先开始加上读锁  
            value = cacheData.get(key);//获取值  
            if(value == null){//判断是否存在值  
                try{  
                    rwl.readLock().unlock();//在开始写之前,首先要释放写锁,否则写锁无法拿到  
                    rwl.writeLock().lock();//获取写锁开始写数据  
		    /* 再次判断该值是否为空,因为如果两个写线程如果都阻塞在这里,当一个线程  
                    *  被唤醒后value的值不为null,当另外一个线程也被唤醒如果不判断就会执行两次写  
		    */
                    if(value == null){
                        value = "queryDB";  
                        cacheData.put(key, value);  
                    }  
                    rwl.readLock().lock();//读完之后重入降级为读锁  
                }finally{  
                    rwl.writeLock().unlock();//最后释放写锁  
                }  
            }  
        }finally{  
            rwl.readLock().unlock();//释放读锁  
        }  
        return value;  
    }  

 

http://blog.csdn.net/lb85858585/article/details/7256278

 

分享到:
评论

相关推荐

    mybatis+redis缓存配置

    Redis是一个开源的高性能键值存储系统,它具有内存存储、低延迟和丰富的数据结构等特点,非常适合用作缓存系统。 ##### 2.1 Redis缓存配置 在MyBatis中配置Redis作为二级缓存,主要涉及以下几个步骤: 1. **引入...

    8、读写锁ReentrantReadWriteLock&StampLock详解.pdf

    - **缓存系统**:读写锁可以在缓存系统中发挥重要作用,允许多个线程同时查询缓存,但只允许一个线程更新缓存。 ### 三、StampLock详解 #### 3.1 StampLock简介 `StampLock`是Java 8引入的一种新的同步机制,它...

    计算机软件-商业源码-利用读写锁保持线程同步.zip

    读写锁的概念源于操作系统理论,但在许多编程语言中都有实现,如Java的`java.util.concurrent.locks.ReentrantReadWriteLock`和C++的`std::shared_timed_mutex`。下面将详细探讨读写锁的工作原理、优缺点以及如何在...

    人工智能-项目实践-多线程-多线程与高并发.zip

    多线程是指在一个程序中同时执行多个线程,这使得计算机能够同时处理多个任务或子任务,提高系统的响应速度和资源利用率。在Java中,Java并发工具包(JUC,Java Concurrency Utilities)是处理多线程问题的核心组件...

    Java多线程与高并发入门到精通-视频教程网盘链接提取码下载.txt

    - **缓存技术**:利用缓存减少对数据库的访问次数,提高系统响应速度。 - **消息队列**:将请求转化为消息放入队列中,由消费者异步处理,降低系统的耦合度。 - **分布式事务**:确保跨服务调用时数据的一致性。 ##...

    MultiThreadedLRUCache:一个简单的多线程缓存。 代码与测试

    在Java编程中,缓存是一种常见的优化技术,用于存储经常访问的数据,以减少对主存或网络的访问,提高系统的响应速度。LRU(Least Recently Used)是最常用的缓存淘汰策略,它将最近最少使用的数据优先淘汰。然而,在...

    Java并发编程全景图.pdf

    Java线程的实现包括操作系统线程,对于线程操作,应该考虑线程池的使用,这涉及到线程的创建、销毁和重用。 4. 线程同步机制 在Java中,线程同步机制是实现线程间协作和数据一致性的关键。synchronized关键字和...

    Mashibing_High_Concurrency-源码.rar

    12. **缓存技术**:使用Redis、Memcached等缓存系统,减少数据库访问,提高高并发场景下的响应速度。 13. **数据库优化**:如索引优化、查询优化、连接池配置等,能够有效应对高并发时的数据库压力。 14. **并行...

    行业分类-设备装置-双模式读写锁.zip

    在实际应用中,双模式读写锁广泛应用于数据库系统、缓存管理、文件系统等领域。例如,在数据库中,当多个查询请求同时到来时,读写锁可以允许这些查询并行执行,而当有更新数据的操作时,会阻塞新的读写请求,直到...

    Java 多线程与并发编程总结.doc

    在操作系统层面,多线程是为了提高系统利用率,使得多个任务能够"同时"执行,但实际上,由于CPU的时钟周期限制,同一时刻只能执行一条指令,而多线程的并发是通过快速切换线程来模拟实现的。 Java中的线程创建主要...

    MCA 多线程&高并发.zip

    - **缓存**:使用Redis或Memcached等缓存系统,减少数据库访问,提高响应速度。 - **数据库优化**:索引、查询优化、分库分表等技术,提高数据库处理能力。 6. **JVM内存模型与并发** - **内存模型**:JMM(Java...

    多读单写锁演示程序

    6. **读写锁的使用场景**:数据库连接池、缓存系统、日志记录、配置文件读取等,都是多读单写锁的理想应用场景。 7. **死锁风险**:虽然读写锁提高了效率,但如果不正确地使用,仍可能导致死锁。例如,如果一个线程...

    性能调优指南--计算机系统Java应用程序(不断完善)代码示例

    在IT行业中,性能调优是提升软件效率的关键环节,尤其对于Java应用程序来说,优化性能能够带来更好的用户体验和更高的系统资源利用率。本指南聚焦于计算机系统中的Java应用程序性能调优,通过代码示例来阐述相关技术...

    Design patterns for concurent objects

    在Java中,`ReentrantReadWriteLock`类提供了一种实现读写锁的方式。 #### 事件驱动编程 事件驱动编程是一种广泛应用于图形用户界面(GUI)和网络应用程序的设计模式。在这种模式下,程序的主要逻辑是由外部事件...

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

    对于 Java 后端开发人员来说,熟悉并发编程是必不可少的技能,尤其在高并发的互联网环境中,合理地利用并发工具和设计模式可以显著提升系统的响应速度和处理能力。 除此之外,Java 后端开发还涉及其他重要知识点,...

    多线程面试题及回答

    - **高效缓存实现:**使用`ReentrantReadWriteLock`来实现高效的缓存。读操作时获取读锁,写操作时获取写锁。由于多个读操作不会相互阻塞,只有写操作时才会有阻塞,因此整体性能较高。 3. **题目3:**Java中`wait...

    《java并发编程的核心方法和框架》

    Java并发编程是Java开发中的重要领域,特别是在多核处理器和分布式系统中,高效地利用并发可以极大地提升程序的性能和响应速度。《java并发编程的核心方法和框架》这本书旨在深入探讨这一主题,帮助开发者掌握Java...

    软件工程中的并发与并行计算.pptx

    - **读写锁模式**:通过ReentrantReadWriteLock和StampedLock等类来实现读写锁的功能。 - **工作窃取模式**:在ForkJoinPool中使用的一种任务调度策略,可以在任务空闲时尝试从其他线程窃取任务来执行。 - **...

    【并发编程】简单化理解AQS和ReentrantLock.pdf

    - **提高缓存效率**:利用缓存一致性原理,减少不必要的数据加载和刷新操作。 - **使用更高效的同步工具**:选择合适的数据结构和算法,比如使用`StampedLock`代替`ReentrantReadWriteLock`等。 #### 6. 错误处理 ...

    并发编程,学习手记.pdf

    【并发编程】是计算机科学中的一个关键领域,特别是在多核心处理器和分布式系统中,它能够充分利用硬件资源,提高程序的执行效率。Java并发编程主要涉及以下几个方面: 1. **Java内存模型(JMM)**:JMM定义了线程...

Global site tag (gtag.js) - Google Analytics