`

通过模板的方式解决缓存被击穿的问题

    博客分类:
  • java
 
阅读更多
1.
package gjp.tools;

import com.alibaba.fastjson.TypeReference;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Lock;

/**
* @Auther: gaojp
* @Date: 2019/4/4 15:12
* @Description:
* 使用模板设计:
* 实现防止缓存被击穿的实现
*
*/
public class CommPlate {
    //缓存数据
   private List<String> list = new ArrayList<String>();

    /**
     *
     * @param name 参数
     * @param value 参数
     * @param plate 调用模板方法时,需要实现的接口
     * @param lock 条件锁
     * @param <T> 返回数据
     * @return
     */
    public <T> T list(String name,String value,Plate<T> plate,final Lock lock)  {
        //缓存查询
        if(list.size() >0){
            return getCache();
        }

        try {
            lock.lock();
                if(list.size() >0){
                    return getCache();
                }
                //数据查询(实际业务)
                T t = plate.show();
                System.out.println("==============数据库查询--------------------");
                //模拟从数据库查询数据
                try {
                    if (list.size() <= 0) {
                        //加入缓存
                        list.add("缓存数据");
                    }
                    Thread.sleep(50000);
                } catch (Exception e) {
                    e.printStackTrace();
                }

                return t;
        }finally {
            lock.unlock();
        }
    }

    public <T> T getCache() {
        String str =  com.alibaba.fastjson.JSON.toJSONString(list);
        System.out.println("*****************=缓存查询查询--------------------");
        return com.alibaba.fastjson.JSON.parseObject(str, new TypeReference<T>(){});
    }
}


2.
package gjp.tools;


/**
* 模板需要实现的接口
* @param <T>
*/
public interface Plate<T> {

    public <T> T show();
}

3.

package gjp.tools;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
* @Auther: gaojp
* @Date: 2019/4/4 15:25
* @Description:
* 使用用模板,防止缓存被击穿
*/
public class TestPlate {

    Lock lock = new ReentrantLock();
    CommPlate commPlate = new CommPlate();

    public List<String> test(){
       return commPlate.list("name", "value", new Plate<List<String>>() {
            @Override
            public List<String> show() {
                List<String> list = new ArrayList<String>();
                list.add("1");

                return list;
            }
        },lock);

    }

    public static void main(String[] args) {
        TestPlate test = new TestPlate();
        List<String> list = test.test();
        for(String item:list){
            System.out.println(item);
        }

        try {
            Thread.sleep(300);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        List<String> list2 = test.test();
        for(String item:list2){
            System.out.println(item);
        }

    }
}




4. 使用多线程进行测试

package gjp.tools;

import java.util.Calendar;
import java.util.List;
import java.util.concurrent.CountDownLatch;

/**
* @Auther: gaojp
* @Date: 2019/4/4 15:08
* @Description:
*/
public class TestLock {

    public int len =5;
    public final CountDownLatch countDownLatch = new CountDownLatch(len);
    public final CountDownLatch countDownLatch2 = new CountDownLatch(len);

    public void test(){
        final TestPlate test = new TestPlate();
        for(int i=0;i<len;i++){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        countDownLatch.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    List<String> list = test.test();
                    for(String item:list){
                        System.out.println("list:"+item);
                    }
                    System.out.println("list-"+countDownLatch.toString()+"---:"+Calendar.getInstance().getTimeInMillis());

                }
            }).start();
            countDownLatch.countDown();

        }

    }

    public void test2(){
        final TestPlate2 test = new TestPlate2();
        for(int i=0;i<len;i++){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        countDownLatch2.await();
                        List<String> list = test.test();
                        for (String item : list) {
                            System.out.println("list2:" + item);
                        }
                        System.out.println("list2-"+countDownLatch.toString()+"---:"+Calendar.getInstance().getTimeInMillis());

                    }catch (Exception ex){
                        ex.printStackTrace();
                    }
                }
            }).start();
            countDownLatch2.countDown();
        }

    }


    public static void main(String[] args) throws InterruptedException {

        long start = Calendar.getInstance().getTimeInMillis();
        new Thread(new Runnable() {
            @Override
            public void run() {
                TestLock testLock = new TestLock();
                testLock.test();
            }
        }).start();


         new Thread(new Runnable() {
            @Override
            public void run() {
                TestLock testLock = new TestLock();
                testLock.test2();
            }
        }).start();

        System.out.println("==================start:"+start);
         Thread.currentThread().join();
//         long end = Calendar.getInstance().getTimeInMillis();
//        System.out.println("运行时间:"+(end-start));

    }
}



此外,还可以通过aop,实现接口,来实行防止缓存被击穿。
分享到:
评论

相关推荐

    面试被问:缓存击穿有什么解决方案.docx

    本文将深入探讨缓存击穿的现象、原因及其解决方案,并通过具体的代码示例来展示如何有效地应对这一挑战。 #### 二、什么是缓存击穿? 缓存击穿通常发生在高并发环境下,当某个热点数据的缓存过期后,短时间内大量...

    35.[视频] Spring Boot集成Redis实现缓存机制【从零开始学Spring Boot】

    - **缓存击穿**:热点数据突然失效,考虑使用互斥锁或分布式锁保护。 通过以上讲解,我们可以看到Spring Boot与Redis集成的缓存机制不仅简化了开发,还提供了强大的缓存功能。结合实际项目需求,合理运用这些知识...

    简历模板—5年.docx

    - **Redis**:熟练掌握Redis的数据结构和应用场景,了解其执行流程、持久化机制等,能有效应对缓存穿透、击穿、雪崩等问题。 #### 4. 消息中间件 - **Kafka/RocketMQ**:熟悉这两种消息队列的基本用法和高级特性,...

    django-redis-chs-readthedocs-io-zh_CN-latest.zip

    - **缓存失效**:合理设置缓存过期策略,避免因大量数据更新导致的缓存击穿问题。 - **监控和统计**:使用Redis的监控工具或集成第三方监控服务,实时了解缓存性能。 总之,`django-redis`为Django项目提供了高效且...

    基于springBoot实现的一个分布式电商系统,本科毕业设计,java web全栈开发学习模板

    4月23日 添加布隆过滤器和Redisson客户端 做了防止缓存穿透和缓存击穿处理 2月24日 手动渲染界面,页面静态化缓存,提高响应时间 2月24日 添加jmeter压测工具 2月25日 实现秒杀抢购功能 2月25日 集成RocketMQ实现...

    程序员简历技能描述怎么写高大上-java篇

    2. 对Redis的底层模型、数据持久化机制、多数据类型的应用、高可用机制有深入理解,熟练应对各种缓存问题,如缓存击穿、缓存穿透和缓存雪崩。 3. 熟悉Couchbase的部署、数据同步、水平扩展和故障转移,熟练使用Redis...

    数据库优化总结.pdf.zip

    了解缓存穿透、缓存雪崩、缓存击穿等问题及其解决方案。 8. **事务与并发控制**:正确设置事务隔离级别,使用乐观锁、悲观锁或MVCC(多版本并发控制)机制,可以有效处理并发问题,保证数据一致性。 9. **监控与...

    java工程师超级面试题

    1. 分布式缓存:了解Redis、Memcached等缓存系统,理解缓存穿透、缓存雪崩、缓存击穿等问题及解决方案。 2. 分布式锁:理解分布式锁的实现原理,如Zookeeper、Redis等。 3. 并发编程:掌握CountDownLatch、...

    字节跳动-后端-质量技术组 一面万字面经 问题+推荐回答

    缓存雪崩、击穿、穿透和解决办法? 简要介绍一下gRPC gRPC的文件是什么后缀(格式) gRPC的代码格式是什么样的?支持定义默认值吗?定义数组的关键字是什么? 除了gRPC你还用过哪些RPC技术栈,你所知道的RPC框架有哪些...

    互联网架构面试题

    - 分布式缓存:Redis、Memcached的使用,以及缓存穿透、缓存雪崩、缓存击穿的问题及其解决方案。 8. **微服务** - 微服务架构的优势与挑战,如何进行服务拆分。 - 服务治理:服务注册与发现、服务调用、熔断、限...

    JAVA架构师课程+面试资料 2.zip

    7. **缓存技术**:了解并能运用Redis、Memcached等缓存系统,理解缓存穿透、缓存雪崩、缓存击穿等问题及其解决方案。 8. **消息队列**:理解消息队列的作用,如RabbitMQ、Kafka、ActiveMQ等,熟悉其工作原理和使用...

    AWS Certified SysOps Administrator - Associate (SOA-C02) 考试样题

    对于ElastiCache for Memcached的高移出指标,这通常表示缓存击穿或内存不足。选项B增加`ConnectionOverhead`参数值可能有助于减少连接压力,而C增加节点数量和D增加节点大小可以增加存储容量,从而降低移出率。...

    Spring使用Redis1

    Redis的雪崩、穿透和击穿问题也是需要考虑的,可以通过合理的缓存策略和设置来避免。 此外,Spring Data Redis提供了多种模板和操作工具,如`StringRedisTemplate`、`HashOperations`、`ListOperations`、`Set...

    阿里云javasdk源码-java-ssm-qingcheng:java-ssm-qingcheng

    Redis(缓存穿透、缓存击穿、缓存雪崩)、elasticsearch搜索(Java rest高级api)、消息中间件(RabbitMQ发送与接受消息)、阿里云通信、开源单点登陆系统CAS、分布式事务、微信扫码支付(微信支付二维码、支付回调逻辑处理...

    PHP-Interview:分享和记录常见的php面试题和面试技巧

    请你说一说你知道的排序算法及其时间复杂度操作系统Redis缓存穿透、缓存击穿和缓存雪崩是什么?设计模式说说你对设计模式中的模板模式的理解吧系统架构软技能程序员修炼之路:你该知道的 7 个必经阶段为什么写这个...

    Spring cloud Feign 深度学习与应用详解

    一艘船会被划分为多个水密舱(舱壁),因而即使少数几个部位被击穿漏水,整艘船并不会被淹没。将这个概念带入到远程调用中,如果所有调用都使用的是同一个线程池来处理,那么很有可能一个缓慢的远程调用会拖垮整个...

    2022面试题6java背诵版本.doc

    在准备2022年的Java面试时,了解和掌握这些常见问题至关重要。下面是对这些问题的详细解答,旨在帮助你深入理解和应用Java相关的编程概念、框架和最佳实践。 1. **Java常用集合及特点**: - ArrayList:动态数组,...

    Spring-Data-Redis:学习Spring Data Redis

    - 注意缓存穿透、缓存雪崩和缓存击穿问题,采取相应措施防止这些情况发生。 以上就是 Spring Data Redis 的核心概念和使用方法,通过学习和实践,你可以充分利用 Redis 的强大功能,提升你的 Java 应用程序的性能...

Global site tag (gtag.js) - Google Analytics