• 基于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 }
  • 相关阅读:
    控件右键菜单的实现以及选中后勾选
    DataGridView控件使用
    return,continue,break的区别
    break和continue的区别 循环终止办法
    事件
    跨线程改变控件属性 线程调用带参数方法
    XML配置文件相关
    抽象类及与接口的区别
    字典
    Oracle学习第一天
  • 原文地址:https://www.cnblogs.com/wei-lai/p/6125297.html
Copyright © 2020-2023  润新知