基于synchronized 或 ReadWriteLock实现 简单缓存机制

  1 package cn.xxx.xxx;
  2 
  3 import java.util.HashMap;
  4 import java.util.Map;
  5 import java.util.concurrent.locks.ReadWriteLock;
  6 import java.util.concurrent.locks.ReentrantReadWriteLock;
  7 
  8 public class CacheDemo_My {
  9 
 10     public static void main(String[] args) {
 11         // 内部类 实例化时需要在 内部类前加static 关键字
 12         final CacheClass cacheClass = new CacheClass();
 13         for (int i = 0; i < 10; i++) { 
 14             new Thread(new Runnable() {
 15  
 16                 @Override
 17                 public void run() {
 18                     Object valueObject = cacheClass.getData("1");
 19                     System.out.println(Thread.currentThread().getName() + " : " + valueObject);
 20                 }
 21             }).start();
 22         } 
 23     }
 24     
 25 
 26     static class CacheClass {
 27         private Map<String, Object> cacheMap = new HashMap<String, Object>();
 28 
 29         /**
 30          * 1.0 没有考虑并发 问题: 从数据库查了两次 
 31          * 从数据库查询数据! 
 32          * 从数据库查询数据!
 33          *  Thread-1 : null 为什么是null,并发了,过程如 Thread-0 所示
 34          *  Thread-2 : aaa 
 35          *  Thread-0 :null  为什么是null,因为第一次读取map中没有值返回null,而cacheMap.put(key, "aaa")后
 36          *             并没有重新赋值给object  所以是null 
 37          *             解决方案是 直接从cacheMap.get(key) 中获取,不要中间环节 object,这里我就不改了
 38          *  Thread-3 : aaa 
 39          *  Thread-4 : aaa 
 40          *  Thread-5 : aaa 
 41          *  Thread-6 : aaa 
 42          *  Thread-7 : aaa 
 43          *  Thread-8: aaa 
 44          *  Thread-9 : aaa
 45          * 
 46          * @param key
 47          * @return
 48          */
 49         // public Object getData(String key) {
 50         // Object value = cacheMap.get(key);
 51         // if (value == null) {
 52         // System.out.println("从数据库查询数据!");
 53         // cacheMap.put(key, "aaa");
 54         // }
 55         // return value;
 56         // }
 57 
 58         /**
 59          * 2.0 使用synchronized 同步 代码块 解决并发问题 实现方式简单 直接加synchronized 关键字
 60          * 
 61          * 从数据库查询数据!
 62          *  Thread-4 : bbb 
 63          *  Thread-1 : bbb 
 64          *  Thread-2 : bbb 
 65          *  Thread-0 : bbb 
 66          *  Thread-3 : bbb
 67          *  Thread-8 : bbb 
 68          *  Thread-7 : bbb 
 69          *  Thread-6 : bbb 
 70          *  Thread-9 : bbb 
 71          *  Thread-5 : bbb
 72          * 
 73          * @param key
 74          * @return
 75          */
 76 //         public synchronized Object getData(String key){
 77 //         
 78 //         if ( cacheMap.get(key)==null) {
 79 //         System.out.println("从数据库查询数据!");
 80 //         cacheMap.put(key, "bbb");
 81 //         }
 82 //         return cacheMap.get(key);
 83 //         }
 84 
 85         /**
 86          * 3.0 使用读写锁  
 87          * 
 88                         从数据库查询数据!
 89             Thread-1 : ccc
 90             Thread-3 : ccc
 91             Thread-4 : ccc
 92             Thread-2 : ccc
 93             Thread-0 : ccc
 94             Thread-5 : ccc
 95             Thread-7 : ccc
 96             Thread-8 : ccc
 97             Thread-9 : ccc
 98             Thread-6 : ccc
 99          */
100         private  ReadWriteLock rwl = new ReentrantReadWriteLock(); 
101         public Object getData(String key) {
102             //加锁了就要try finally ,避免异常情况下 代码一直被锁
103             rwl.readLock().lock(); 
104             try {
105                 if (cacheMap.get(key) == null) { 
106                     try{
107                         //读锁 解掉 是为了写锁 加锁
108                         rwl.readLock().unlock();
109                         //加锁了就要try finally ,避免异常情况下 代码一直被锁
110                         rwl.writeLock().lock();
111                         // 避免第一个线程写完数据,后面的线程接着写
112                         if (cacheMap.get(key) == null) {
113                             System.out.println("从数据库查询数据!");
114                             cacheMap.put(key, "ccc");
115                         }
116                     }
117                     finally{
118                         rwl.writeLock().unlock(); 
119                     } 
120                     rwl.readLock().lock();
121                 }
122             } finally {
123                 rwl.readLock().unlock();
124             }
125 
126             return cacheMap.get(key);
127         }
128     }
129 }
原文地址:https://www.cnblogs.com/wei-lai/p/6125297.html