通过模板的方式解决缓存被击穿的问题
程序员文章站
2022-06-21 21:13:57
...
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,实现接口,来实行防止缓存被击穿。
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,实现接口,来实行防止缓存被击穿。
上一篇: ORACLE开窗函数语法和使用介绍
推荐阅读
-
怎样获取最新版的javascript文件,解决被浏览器缓存的问题
-
关于缓存穿透,缓存击穿,缓存雪崩,热点数据失效问题的解决方案(转)
-
通过模板的方式解决缓存被击穿的问题
-
通过模板的方式解决缓存被击穿的问题
-
通过yeoman、gulp、angular编写前段时的html模板处理,打包后找不到html的问题解决_html/css_WEB-ITnose
-
搞了一个微信网站,两套模板切换,但是有缓存,不能立即看的效果,要重新登微信才行 ,这个问题怎么解决
-
IIS7.0通过FastCGI方式运行PHP遇到的一些问题及解决方法
-
IIS7.0通过FastCGI方式运行PHP遇到的一些问题及解决方法
-
easypoi利用模板导出图片到Excel;解决easypoi导出图片到合并单元格单元格被拉伸的问题
-
怎样获取最新版的javascript文件,解决被浏览器缓存的问题