zoukankan      html  css  js  c++  java
  • 利用读写锁实现缓存系统

    读写锁:分为读锁和写锁,多个读锁不互斥,读锁与写锁互斥,这是由jvm自己控制的,你只要上好相应的锁即可。如果你的代码只读数据,可以很多人同时读,但不能同时写,那就上读锁;如果你的代码修改数据,只能有一个人在写,且不能同时读取,那就上写锁。总之,读的时候上读锁,写的时候上写锁!

    三个线程读数据,三个线程写数据示例:
    可以同时读,读的时候不能写,不能同时写,写的时候不能读。
    读的时候上读锁,读完解锁;写的时候上写锁,写完解锁。
    注意finally解锁。

    设计一个缓存系统
    缓存系统:你要取数据,需调用我的public Object getData(String key)方法,我要检查我内部有没有这个数据,如果有就直接返回,如果没有,就从数据库中查找这个数,查到后将这个数据存入我内部的存储器中,下次再有人来要这个数据,我就直接返回这个数不用再到数据库中找了。你要取数据不要找数据库,来找我。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    package com.ljq.test.thread;
     
    import java.util.HashMap;
    import java.util.Map;
    import java.util.concurrent.locks.ReadWriteLock;
    import java.util.concurrent.locks.ReentrantReadWriteLock;
     
    /**
     * 设计一个缓存系统
     *
     *
     * @author Administrator
     *
     */
    public class CacheDemo {
     
        private Map<String, Object> cache = new HashMap<String, Object>();
     
        public static void main(String[] args) {
            String key = "name";
            CacheDemo cacheDemo = new CacheDemo();
            System.out.println(cacheDemo.getData(key)); //从数据库获取数据
            System.out.println(cacheDemo.getData(key)); //从缓存获取数据
            System.out.println(cacheDemo.getData(key)); //从缓存获取数据
        }
     
        private ReadWriteLock rwl = new ReentrantReadWriteLock();
     
        public Object getData(String key) {
            rwl.readLock().lock(); //上读锁
            Object value = null;
            try {
                value = cache.get(key); //先查询内部存储器中有没有要的值
                if (value == null) { //如果没有,就去数据库中查询,并将查到的结果存入内部存储器中
                    //释放读锁、上写锁
                    rwl.readLock().unlock();
                    rwl.writeLock().lock();
                    try {
                        if (value == null) { //再次进行判断,防止多个写线程堵在这个地方重复写
                            System.out.println("read data from database");
                            value = "张三";
                            cache.put(key, value);
                        }
                    finally {
                        //设置完成 释放写锁
                        rwl.writeLock().unlock();
                    }
                    //恢复读写状态
                    rwl.readLock().lock();
                }else{
                    System.out.println("read data from cache");
                }
            finally {
                rwl.readLock().unlock(); //释放读锁
            }
            return value;
        }
    }

    返回结果:

    本文转自:http://www.cnblogs.com/linjiqin/p/4504601.html 感谢作者

  • 相关阅读:
    Git 基础
    SharePoint 2013 对象模型操作"网站设置"菜单
    SharePoint 2013 隐藏部分Ribbon菜单
    SharePoint 2013 Designer系列之数据视图筛选
    SharePoint 2013 Designer系列之数据视图
    SharePoint 2013 Designer系列之自定义列表表单
    SharePoint 2013 设置自定义布局页
    SharePoint 2013 "通知我"功能简介
    SharePoint 2013 创建web应用程序报错"This page can’t be displayed"
    SharePoint 禁用本地回环的两个方法
  • 原文地址:https://www.cnblogs.com/panxuejun/p/5957180.html
Copyright © 2011-2022 走看看