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

阅读更多
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 list = new ArrayList();

    /**
     *
     * @param name 参数
     * @param value 参数
     * @param plate 调用模板方法时,需要实现的接口
     * @param lock 条件锁
     * @param 返回数据
     * @return
     */
    public T list(String name,String value,Plate 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 getCache() {
        String str =  com.alibaba.fastjson.JSON.toJSONString(list);
        System.out.println("*****************=缓存查询查询--------------------");
        return com.alibaba.fastjson.JSON.parseObject(str, new TypeReference(){});
    }
}


2.
package gjp.tools;


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

    public 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 test(){
       return commPlate.list("name", "value", new Plate>() {
            @Override
            public List show() {
                List list = new ArrayList();
                list.add("1");

                return list;
            }
        },lock);

    }

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

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

        List 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            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        countDownLatch.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    List 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            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        countDownLatch2.await();
                        List 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,实现接口,来实行防止缓存被击穿。

你可能感兴趣的:(通过模板的方式解决缓存被击穿的问题)