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

目录

一、说明

  • 1.针对于读多写少的情况
  • 2.先查缓存,没有再去查库

二、代码示例

2.1 pom依赖
复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.learning</groupId>
    <artifactId>jdbc</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.21</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.3.26</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.6</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.16</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.26</version>
        </dependency>
    </dependencies>
</project>
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<CacheKey, Object> 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> T queryOne(Class<T> 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> T queryDatabase(Class<T> beanClass, String sql, Object[] args) {
        BeanPropertyRowMapper beanPropertyRowMapper = new BeanPropertyRowMapper<T>();
        beanPropertyRowMapper.setMappedClass(beanClass);
        System.out.println("sql:"+sql);
        List<T> 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();
        }
    }
}
2.3 实体类
复制代码
package com.learning;

import lombok.Data;

@Data
public class Student {
    private String id;
    private String name;
    private int age;
}

三、示例截图

相关推荐
庞轩px1 天前
AQS(AbstractQueuedSynchronizer)源码深度解析:从CLH队列到ReentrantLock实现
java·并发编程·juc·aqs·reentrantlock
C++chaofan3 天前
RPC框架容错机制深度解析
java·开发语言·后端·性能优化·高并发·juc·容错机制
C++chaofan3 天前
RPC框架负载均衡机制深度解析
java·开发语言·负载均衡·juc·synchronized·
曼彻斯特的海边5 天前
synchronized优化原理
jvm·juc·synchronized
C++chaofan15 天前
JUC 并发编程:不可变对象、享元模式与自定义连接池 学习笔记
java·享元模式·并发编程·连接池·juc·不可变对象
C++chaofan16 天前
JUC 并发编程:对可见性、有序性与 volatile的理解
java·开发语言·spring·java-ee·juc·synchronized·
西门吹雪分身1 个月前
JUC之公平锁与非公平锁
java·并发·juc·
西门吹雪分身1 个月前
JUC之可重入锁
java·juc·死锁·公平锁·非公平锁
长安城没有风2 个月前
Java 高并发核心编程 ----- 线程池原理与实践(上)
java·juc
长安城没有风2 个月前
Java 高并发核心编程 ----- 初识多线程(下)
java·juc