项目历程—缓存系统V3
根据请求数据的平均时间间隔来将数据放入缓存系统之中:
实现效果如下:
实现代码如下:
(一)创建key的封装类:
因为需要请求key,所以为了便于给key添加其他的属性,这里先创建一个类,不仅有key,更有后期需要用到的其他变量:
数据总数变量DataCount
5/10/100/1000次访问的总时间timeAll
上一次访问的时间lastTime
访问的次数count
以及用来获取时间间隔的方法,逻辑如下:
1.记录该次访问时间,倘若上一次没访问过,(lastTime == 0),则把此次作为第一次(lastTime = thisTime);若上一访问过,则将这两次的时间间隔计算出,并加入到总间隔时间
2.待访问等于或超过规定的次数(5/10/100/1000次)计算出间隔值并返回。
3.根据获取到的时间间隔,判断有没有资格被放入缓存区(Store方法)
4.创建store方法,拟写放入逻辑。
package DemoProject.fjm0816.fjm0901.fjm0901Request;public class KeyData {String key;String value;public KeyData(String key,String value){this.key = key;this.value = value;}//创建数据总数变量。static long DataCount5 = 0;static long DataCount10 = 0;static long DataCount100 = 0;static long DataCount1000 = 0;// 5/10/100/1000次访问的总时间static long time5All;static long time10All;static long time100All;static long time1000All;//上一次访问的时间static long lastTime = 0;//记录访问的次数:static int count5 = 0;static int count10 = 0;static int count100 = 0;static int count1000 = 0;//获取平均间隔时间:不真的创建出5/100/100/1000个时间点变量,而是用一个时间段变量持续递增4次最后取平均值public static long getTime5(long thisTime){long time5 = 0 ;if(lastTime == 0){lastTime = thisTime;count5 ++;}else {time5All += thisTime - lastTime;count5 ++;if(count5 == 5){time5 = time5All / 4;}else if(count5 > 5){time5 = (time5 * 3 + (thisTime - lastTime)) / 4;}}return time5;}public static long getTime10(long thisTime){long time10 = 0 ;if(lastTime == 0){lastTime = thisTime;count10 ++;}else {time10All += thisTime - lastTime;count10 ++;if(count10 == 10){time10 = time10All / 9;}else if(count10 > 10){time10 = (time10 * 8 + (thisTime - lastTime)) / 9;}}return time10;}public static long getTime100(long thisTime){long time100 = 0 ;if(lastTime == 0){lastTime = thisTime;count100 ++;}else {time100All += thisTime - lastTime;count100 ++;if(count100 == 100){time100 = time100All / 99;}else if(count100 > 100){time100 = (time100 * 98 + (thisTime - lastTime)) / 99;}}return time100;}public static long getTime1000(long thisTime){long time1000 = 0 ;if(lastTime == 0){lastTime = thisTime;count1000 ++;}else {time1000All += thisTime - lastTime;count1000 ++;if(count1000 == 1000){time1000 = time100All / 999;}else if(count1000 > 1000){time1000 = (time1000 * 998 + (thisTime - lastTime)) / 999;}}return time1000;}//得出时间,并根据时间加入各自的缓存区public void getTimeAndStore(long thisTime,String key ,String value){//会把当前的时间间隔的出来long time5R = getTime5(thisTime);long time10R =getTime10(thisTime);long time100R =getTime100(thisTime);long time1000R =getTime1000(thisTime);//根据四个时间间隔,推断是否可以加入各自的缓存区Store(time5R,time10R,time100R,time1000R,key,value);}public static void Store(long time5R,long time10R,long time100R,long time1000R,String key,String value){//如果五次的平均间隔时间小于5秒,且真的访问了超过五次。则存入缓存区if(count5 >= 5 && time5R <= 5){DataCount5 ++;RequestMain.hashMap5.put(key ,value + "_" + DataCount5 + "_5" );}if(count10 >= 10 && time10R <= 25){DataCount10 ++;RequestMain.hashMap10.put(key ,value + "_" + DataCount10 + "_10" );}if(count100 >= 100 && time100R <= 50){DataCount100 ++;RequestMain.hashMap100.put(key ,value + "_" + DataCount100 + "_100" );}if(count1000 >= 1000 && time1000R <= 100){DataCount1000 ++;RequestMain.hashMap1000.put(key ,value + "_" + DataCount1000 + "_1000" );}}//每次访问过后都立马判断此时的间隔时间满不满足标准,满足则加入缓存区中,因此也需要一个循环体,自动循环查找各自的数据,并且间隔时间随机,模拟真实访问频率}
(二)创建缓存区类,有四个缓存用的哈希表,有一个后续会存数据并遍历取之的哈希表
package DemoProject.fjm0816.fjm0901.fjm0901Request;//在这个主函数中,我将创建出四个存储数据的方法,以及四个用来缓存数据的结构import java.util.HashMap;public class RequestField {//四个时间对应的缓存结构static HashMap<String,String> hashMap5 = new HashMap<>();static HashMap<String,String> hashMap10 = new HashMap<>();static HashMap<String,String> hashMap100 = new HashMap<>();static HashMap<String,String> hashMap1000 = new HashMap<>();//待选数据的数据池;static HashMap<String,String> hashMapRandom = new HashMap<>();}
(三)创建主函数类。向待遍历的那个哈希表中预先存入数据,然后循环请求数据,当各自的哈希表大小达到标准后退出循环,检验其中的数据。
package DemoProject.fjm0816.fjm0901.fjm0901Request;import org.apache.commons.lang3.RandomStringUtils;import java.util.Map;public class KeyDataMain {public static void main(String[] args) {//存入1000个随机数据KeyDataMain keyDatamain = new KeyDataMain();keyDatamain.RanData();while(true){try {Thread.sleep(200);} catch (InterruptedException e) {throw new RuntimeException(e);}
// System.out.println("进入此循环");for(Map.Entry<String,String> entry : RequestField.hashMapRandom.entrySet()){KeyData keyData = new KeyData(entry.getKey(),entry.getValue());keyData.getTimeAndStore(System.currentTimeMillis(),entry.getKey(),entry.getValue());
// System.out.println("开始存入数据");}System.out.println("hashMap5的大小为:" + RequestField.hashMap5.size() );System.out.println("hashMap10的大小为:" + RequestField.hashMap10.size() );System.out.println("hashMap100的大小为:" + RequestField.hashMap100.size() );System.out.println("hashMap1000的大小为:" + RequestField.hashMap1000.size() );if(RequestField.hashMap5.size() >= 600 && RequestField.hashMap10.size() >= 1000 && RequestField.hashMap100.size() >= 1000 && RequestField.hashMap1000.size() >= 1000){break;}}System.out.println("缓存5区存进来的数据为:");for(Map.Entry<String,String> entry : RequestField.hashMap5.entrySet()){System.out.print(entry.getKey() + "——" + entry.getValue() + " ");}System.out.println();System.out.println("缓存10区存进来的数据为:");for(Map.Entry<String,String> entry : RequestField.hashMap10.entrySet()){System.out.print(entry.getKey() + "——" + entry.getValue() + " ");}System.out.println();System.out.println("缓存100区存进来的数据为:");for(Map.Entry<String,String> entry : RequestField.hashMap100.entrySet()){System.out.print(entry.getKey() + "——" + entry.getValue() + " ");}System.out.println();System.out.println("缓存1000区存进来的数据为:");for(Map.Entry<String,String> entry : RequestField.hashMap1000.entrySet()){System.out.print(entry.getKey() + "——" + entry.getValue() + " ");}}public void RanData(){while (true){String ranKey = RandomStringUtils.randomAlphabetic(2);String ranValue = RandomStringUtils.randomAlphabetic(2);RequestField.hashMapRandom.put(ranKey,ranValue);if(RequestField.hashMapRandom.size() == 1000){break;}}System.out.println(RequestField.hashMapRandom.size());}
}
至此可以实现该效果。
补充:
在RanData()方法里面有一个类叫做RandomStringUtils,这个类原java并没有,需要通过第三方库导入,具体导入方法看作者的这个博客
https://blog.csdn.net/2401_86264846/article/details/151186667?spm=1001.2014.3001.5501