备注:实际应用场景中我这里不是实现自增 , 上边代码自增目的:测试是否能够在高并发下修改同一个key时实现锁的功能 。
实际应用:高并发使用redis同一个key存储统计TOPN结果
需求:
1)拥有多个记录 , 每条记录数据格式:日期 , 统计指标1 , 统计指标2 , 统计指标3 , 统计指标4
2)要求分别统计出4个指标的最大值 , 并记录各自指标最大值时对应的记录 。
3)记录中各个字段的模拟公式:
// 数据格式:// 第一列:日期// 第二列:f(x) = x*0.7+1(x自然数) 最大值 45.1// 第三列:f(x)= -x*x+20x+1(自然数) a=-1,b=20,c=1 , 当x=-b/2a时 y 最大值:-10*10+20*10+1=101// 第四列:f(x)= -x*x+30x+1(自然数) a=-1,b=30,c=1 , 当x=-b/2a时 y 最大值:-15*15+30*15+1=445-225+1=221// 第五列:f(x)= 640/(x+1)(x自然数) 最大值 640 使用mutil+watch实现:
首先 , 把最终统计结果存储到redis的key(lock_test)中 , lock_test是一个hash类型 , 其中存储四个键值对 , 每个键值对分别存储各自的指标最大值时对应的记录 。
指标配置项存储到FeildConfig.java
static class FieldConfig { private String key; private Integer index; public String getKey() { return key; } public void setKey(String key) { this.key = key; } public Integer getIndex() { return index; } public void setIndex(Integer index) { this.index = index; } public FieldConfig(String key, Integer index) { super(); this.key = key; this.index = index; } }在测试类的static构造函数中初始化各自指标在一条记录的中索引位置 , 及一共包含的指标类型:
public class Test_Lock3 {。。。final static List<FieldConfig> keys = new ArrayList<FieldConfig>(); static { keys.add(new FieldConfig("101", 1)); keys.add(new FieldConfig("102", 2)); keys.add(new FieldConfig("103", 3)); keys.add(new FieldConfig("104", 4)); }。。。}备注:101代表指标1 , 对应在被统计记录中的第1索引位置(备注:这里索引是对记录按照“,”分割后的数组索引位置) 。
制作测试数据:
List<String> dataItems=new ArrayList<String>(); // 数据格式: // 第一列:日期 // 第二列:f(x) = x*0.7+1(x自然数) 最大值 45.1 // 第三列:f(x)= -x*x+20x+1(自然数) a=-1,b=20,c=1 , 当x=-b/2a时 y 最大值:-10*10+20*10+1=101 // 第四列:f(x)= -x*x+30x+1(自然数) a=-1,b=30,c=1 , 当x=-b/2a时 y 最大值:-15*15+30*15+1=445-225+1=221 // 第五列:f(x)= 640/(x+1)(x自然数) 最大值 640for(int x=0;x<threahSize;x++){ String dataItem = "2018-07-29 00:00:00," + (x*0.7d+1) + "," + (-1d*x*x+20*x+1) + "," + (-1d*x*x+30*x+1) + "," + (640d/(x+1)); dataItems.add(dataItem); }以下是整体测试代码:
package com.dx.es;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.concurrent.CountDownLatch;import redis.clients.jedis.Jedis;import redis.clients.jedis.JedisPool;import redis.clients.jedis.Transaction;public class Test_Lock3 { final static JedisPool pool = RedisUtil.getPool(); final static List<FieldConfig> keys = new ArrayList<FieldConfig>(); static { keys.add(new FieldConfig("101", 1)); keys.add(new FieldConfig("102", 2)); keys.add(new FieldConfig("103", 3)); keys.add(new FieldConfig("104", 4)); } public static void main(String[] args) { int threahSize = 64; final CountDownLatch threadsCountDownLatch = new CountDownLatch(threahSize); Jedis jedis = pool.getResource(); jedis.del("lock_test");List<String> dataItems=new ArrayList<String>(); // 数据格式: // 第一列:日期 // 第二列:f(x) = x*0.7+1(x自然数) 最大值 45.1 // 第三列:f(x)= -x*x+20x+1(自然数) a=-1,b=20,c=1 , 当x=-b/2a时 y 最大值:-10*10+20*10+1=101 // 第四列:f(x)= -x*x+30x+1(自然数) a=-1,b=30,c=1 , 当x=-b/2a时 y 最大值:-15*15+30*15+1=445-225+1=221 // 第五列:f(x)= 640/(x+1)(x自然数) 最大值 640for(int x=0;x<threahSize;x++){ String dataItem = "2018-07-29 00:00:00," + (x*0.7d+1) + "," + (-1d*x*x+20*x+1) + "," + (-1d*x*x+30*x+1) + "," + (640d/(x+1)); dataItems.add(dataItem); }for (int i = 0; i < threahSize; i++) { Jedis jedisT = pool.getResource();Runnable handler = new MyRunable(jedisT, threadsCountDownLatch, dataItems.get(i)); new Thread(handler).start(); } // 等待所有并行子线程任务完成 。try { threadsCountDownLatch.await(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("complete"); Map<String, String> values = jedis.hgetAll("lock_test"); jedis.close(); System.out.println(values); } static class MyRunable implements Runnable { private Jedis jedis = null; private CountDownLatch threadsCountDownLatch = null; private String newLine = null; public MyRunable(Jedis jedis, CountDownLatch threadsCountDownLatch, String newLine) { this.jedis = jedis; this.threadsCountDownLatch = threadsCountDownLatch; this.newLine = newLine; } public void run() { while (true) { this.jedis.watch("lock_test"); Map<String, String> newValues = new HashMap<String, String>(); Map<String, String> oldValues = this.jedis.hgetAll("lock_test");String newValueStr=""; for (FieldConfig key : keys) { if (oldValues.containsKey(key.getKey())) { Double oldValue = https://www.isolves.com/it/sjk/Redis/2019-07-19/Double.valueOf(oldValues.get(key.getKey()).split(",")[key.getIndex()]); Double newValue = Double.valueOf(newLine.split(",")[key.getIndex()]); if (newValue > oldValue) { newValues.put(key.getKey(), newLine); newValueStr=newLine; } else { newValues.put(key.getKey(), oldValues.get(key.getKey())); newValueStr=oldValues.get(key.getKey()); } } else { newValues.put(key.getKey(), newLine); newValueStr=newLine; } } Transaction tx = this.jedis.multi(); tx.hmset("lock_test", newValues); List
推荐阅读
- 男性生殖器上长疙瘩该怎么解决呢?
- 酵素|解决头发打结、毛燥、掉落,5个保养方法重拾光泽柔顺的发质!
- 玩LOL电脑很卡怎么办?解决方案五步走 玩英雄联盟卡怎么办
- 不花钱,这波操作帮你轻松解决 apple id密码忘了
- 淘宝直播流量突然下降怎么解决 淘宝直播间流量突然下降
- redis事务不具有回滚机制,那么它是如何进行事务控制的
- 微信 小程序 POST请求中文乱码的解决方法
- 怎么解决 无法访问 您可能没有权限使用网络资源
- 分布式 MIMO 与无蜂窝移动通信
- office2007软件打开时弹出报错SETUP ERROR的解决方法