1:使用redis自带的分布式锁,set px nx
set key 1 px 60000 nx
px 过期时间 nx 分布式锁参数,只有当不存在时,才可设置成功
public String getUser(String key) {
User user = new User();
// 链接缓存
Jedis jedis = redisUtil.getJedis();
// 查询缓存
String userJson = jedis.get(key);
if(StringUtils.isNotBlank(userJson)){//if(userJson!=null&&!userJson.equals(""))
user = JSON.parseObject(userJson, User.class);
}else{ // 如果缓存中没有,查询mysql
// 设置分布式锁
String token = UUID.randomUUID().toString();
String OK = jedis.set(key + ":lock", token, "nx", "px", 10*1000);// 拿到锁的线程有10秒的过期时间
if(StringUtils.isNotBlank(OK)&&OK.equals("OK")){
// 设置成功,有权在10秒的过期时间内访问数据库
user = getByIdFromDb(key);
if(user!=null){
// mysql查询结果存入redis
jedis.set(key+":info",JSON.toJSONString(user));
}else{
// 数据库中不存在该key
// 为了防止缓存穿透将,null或者空字符串值设置给redis
jedis.setex(key+":info",60*3,JSON.toJSONString(""));
}
// 在访问mysql后,将mysql的分布锁释放
String lockToken = jedis.get(key + ":lock");
if(StringUtils.isNotBlank(lockToken)&&lockToken.equals(token)){
//jedis.eval("lua");可与用lua脚本,在查询到key的同时删除该key,防止高并发下的意外的发生
jedis.del(key + ":lock");// 用token确认删除的是自己的key的锁
}
}else{
// 设置失败,自旋(该线程在睡眠几秒后,重新尝试访问本方法)
return getUser(key);
}
}
jedis.close();
return user;
}
reids的工具类RedisUtil

//reids的工具类(用来将redis的池初始化到spring容器中)
public class RedisUtil {
private JedisPool jedisPool;
public void initPool(String host,int port ,int database){
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxTotal(200);
poolConfig.setMaxIdle(30);
poolConfig.setBlockWhenExhausted(true);
poolConfig.setMaxWaitMillis(10*1000);
poolConfig.setTestOnBorrow(true);
jedisPool=new JedisPool(poolConfig,host,port,20*1000);
}
public Jedis getJedis(){
Jedis jedis = jedisPool.getResource();
return jedis;
}
}
redis的配置类RedisConfig

//spring整合redis的配置类 将redis的链接池创建到spring的容器中
@Configuration
public class RedisConfig {
//读取配置文件中的redis的ip地址
@Value("${spring.redis.host:disabled}")
private String host;
@Value("${spring.redis.port:0}")
private int port ;
@Value("${spring.redis.database:0}")
private int database;
@Bean
public RedisUtil getRedisUtil(){
if(host.equals("disabled")){
return null;
}
RedisUtil redisUtil=new RedisUtil();
redisUtil.initPool(host,port,database);
return redisUtil;
}
}
2:redisson框架,一个redis的带有juc的lock功能的客户端的实现(既有jedis的功能,又有juc的锁功能)
来源:https://www.cnblogs.com/fuyublog/p/12010848.html
