• 【juc】ReentrantReadWriteLock之缓存(仅当学习)


    一、说明
    • 1.针对于读多写少的情况
    • 2.先查缓存,没有再去查库
    二、代码示例
    2.1 pom依赖
    
    
        4.0.0
    
        com.learning
        jdbc
        1.0-SNAPSHOT
    
        
            8
            8
        
    
        
            
                mysql
                mysql-connector-java
                8.0.21
            
            
                org.springframework
                spring-jdbc
                5.3.26
            
            
                org.mybatis
                mybatis
                3.5.6
            
            
                com.alibaba
                druid
                1.2.16
            
            
                org.projectlombok
                lombok
                1.18.26
            
        
    
    
    • 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
    2.2 示例代码
    package com.learning;
    
    import com.alibaba.druid.pool.DruidDataSource;
    import org.apache.ibatis.cache.CacheKey;
    import org.springframework.jdbc.core.BeanPropertyRowMapper;
    import org.springframework.jdbc.core.JdbcTemplate;
    
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.concurrent.locks.ReentrantReadWriteLock;
    
    public class DataCache {
        private ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
        private Map map = new HashMap<>();
    
        private static DruidDataSource druidDataSource = new DruidDataSource();
        private static JdbcTemplate jdbcTemplate;
        static {
            druidDataSource.setUrl("jdbc:mysql://127.0.0.1:3306/test?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true&allowPublicKeyRetrieval=true");
            druidDataSource.setUsername("root");
            druidDataSource.setPassword("root");
            jdbcTemplate = new JdbcTemplate(druidDataSource);
        }
    
        public  T queryOne(Class beanClass, String sql, Object... args){
            // 从缓存中查找,找到则直接返回
            CacheKey key = new CacheKey(new Object[]{sql, args});
            reentrantReadWriteLock.readLock().lock();
            try{
                T value = (T)map.get(key);
                if(value != null){
                    return value;
                }
            }finally{
                reentrantReadWriteLock.readLock().unlock();
            }
            reentrantReadWriteLock.writeLock().lock();
            try{
                // 多个线程,再获取一遍,检查一下,是否有线程写入成功了
                T value = (T) map.get(key);
                if(value == null){
                    // 缓存中没有,查询数据库
                    value = queryDatabase(beanClass, sql, args);
                    map.put(key, value);
                }
                return value;
            }finally {
                reentrantReadWriteLock.writeLock().unlock();
            }
        }
    
        private  T queryDatabase(Class beanClass, String sql, Object[] args) {
            BeanPropertyRowMapper beanPropertyRowMapper = new BeanPropertyRowMapper();
            beanPropertyRowMapper.setMappedClass(beanClass);
            System.out.println("sql:"+sql);
            List list = jdbcTemplate.query(sql, args, beanPropertyRowMapper);
            return list.get(0);
        }
    
        public static void main(String[] args) {
            DataCache dataCache = new DataCache();
            String sql = "select * from student where id = ?";
            Object[] param = new Object[]{1};
            for (int i = 0; i < 10; i++) {
                new Thread(()->{
                    Student student = dataCache.queryOne(Student.class, sql, param);
                    System.out.println(student);;
                }).start();
            }
        }
    }
    
    • 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
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    2.3 实体类
    package com.learning;
    
    import lombok.Data;
    
    @Data
    public class Student {
        private String id;
        private String name;
        private int age;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    三、示例截图

    在这里插入图片描述

  • 相关阅读:
    ICP算法加速优化--多线程和GPU
    tokenizers Tokenizer 类
    动态顺序表实现栈:顺序栈
    zynq pl访问ps ddr
    redis笔记
    halcon实时采集数据
    10款Visual Studio实用插件
    java中转义字符的源码数据格式,内存存储数据格式和转换json后的数据格式
    区块链技术与人工智能如何相互赋能
    2023秋招面试准备
  • 原文地址:https://blog.csdn.net/qq_32088869/article/details/132668270