Redis常用操作

1:redis常用操作:

java 复制代码
package com.shunaier.hhhh.biz.utils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.shunaier.hhhh.common.enums.SystemErrorEnum;
import com.shunaier.hhhh.common.exception.SNEBizException;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.RedisConnectionFailureException;
import org.springframework.data.redis.connection.DataType;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisStringCommands.SetOption;
import org.springframework.data.redis.core.DefaultTypedTuple;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.data.redis.core.types.Expiration;
import org.springframework.data.redis.support.atomic.RedisAtomicLong;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;

@Component
@SuppressWarnings({"hiding", "rawtypes", "unchecked"})
public final class RedisUtils {

	private static RedisTemplate redisTemplate;

	private static RedissonClient redissonClient;

    private static String host;
 
    private static String password;
 
    private static Integer port;
    
    private static int databaseIndex;
    
    @Value("${redis.server.host}")
	public void setHost(String host) {
    	RedisUtils.host = host;
	}

    @Value("${redis.server.password}")
	public void setPassword(String password) {
    	RedisUtils.password = password;
	}

    @Value("${redis.server.port}")
	public void setPort(Integer port) {
    	RedisUtils.port = port;
	}

    @Value("${redis.server.database:0}")
	public void setDatabaseIndex(int databaseIndex) {
    	RedisUtils.databaseIndex = databaseIndex;
	}

	//锁
	private static RedissonClient redissonClient() {
		if (redissonClient == null) {
			Config config = new Config();
			config.useSingleServer()
					.setAddress(String.format("redis://%s:%s", host, port))
					.setDatabase(databaseIndex)
					.setPassword(password);
			redissonClient = Redisson.create(config);
		}
		return redissonClient;
	}

	@Autowired
    public void setRedisTemplate(RedisTemplate redisTemplate) {
		RedisUtils.redisTemplate = redisTemplate;
    }

	/**
	 * 存入字符串
	 * @param key 键
	 * @param value 值
	 */
	public static void set(Object key, Object value) {
		try {
			redisTemplate.opsForValue().set(key, value);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 不存在便存入字符串
	 * @param key 键
	 * @param value 值
	 */
	public static Boolean setIfAbsent(Object key, Object value) {
		try {
			return redisTemplate.opsForValue().setIfAbsent(key, value);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 批量存入字符串
	 * @param map 键-值
	 */
	public static void setAll(Map<Object, Object> map) {
		try {
			redisTemplate.opsForValue().multiSet(map);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 存入字符串 并 设置过期时间
	 * @param key 键
	 * @param value 值
	 * @param time 时间
	 * @param unit 时间粒度
	 */
	public static void setAndTimeout(Object key, Object value, long time, TimeUnit unit) {
		try {
			redisTemplate.opsForValue().set(key, value, time, unit);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 不存在便存入字符串 并 设置过期时间
	 * @param key 键
	 * @param value 值
	 * @param time 时间
	 * @param TimeUnit unit 时间粒度
	 */
	public static Boolean setIfAbsentAndTimeout(Object key, Object value, long time, TimeUnit unit) {
		try {
			return redisTemplate.opsForValue().setIfAbsent(key, value, time, unit);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 批量存入 map
	 * @param map
	 * @return
	 */
	public static void setByPipelined(Map<String, String> map) {
		try {
			redisTemplate.executePipelined(new RedisCallback<Object>() {

				@Override
	            public String doInRedis(RedisConnection connection) throws DataAccessException {
					for (Entry<String, String> entry : map.entrySet()) {
						connection.set(entry.getKey().getBytes(), entry.getValue().getBytes());
					}
	                return null;
	            }

	        });
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 批量存入-过期 map
	 * @param map
	 * @return
	 */
	public static void setByPipelinedAndTimeout(Map<String, String> map, long time, TimeUnit unit) {
		try {
			redisTemplate.executePipelined(new RedisCallback<Object>() {

				@Override
	            public String doInRedis(RedisConnection connection) throws DataAccessException {
					for (Entry<String, String> entry : map.entrySet()) {
						connection.set(entry.getKey().getBytes(), entry.getValue().getBytes(), Expiration.from(time, unit), SetOption.UPSERT);
					}
	                return null;
	            }

	        });
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 获取所有的key
	 */
	public static Set<Object> keys() {
		try {
			return redisTemplate.keys("*");
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 关键字模糊获取所有的key
	 * @param prex
	 */
	public static Set<Object> keys(String prex) {
		try {
			return redisTemplate.keys("*" + prex + "*");
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 修改key
	 * @param oldKey
	 * @param newKey
	 */
	public static void renameKey(Object oldKey, Object newKey) {
		try {
			redisTemplate.rename(oldKey, newKey);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 判断key的类型
	 * @param key
	 * @return
	 */
	public static String type(String key) {
		try {
			DataType dataType = redisTemplate.type(key);
			return dataType.code();
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 获取字符串
	 * @param key 键
	 * @return
	 */
	public static Object get(Object key) {
		try {
			return redisTemplate.opsForValue().get(key);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 批量获取字符串
	 * @param keys 键
	 * @return
	 */
	public static List<Object> multiGet(List<Object> keys) {
		try {
			return redisTemplate.opsForValue().multiGet(keys);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 批量获取
	 * @param keys 键
	 * @return
	 */
	public static List<Object> getByPipelined(List<Object> keys) {
		try {
			return redisTemplate.executePipelined(new RedisCallback<String>() {
	            @Override
	            public String doInRedis(RedisConnection connection) throws DataAccessException {
	            	for (int i = 0; i < keys.size(); i++) {
	            		connection.get(keys.get(i).toString().getBytes());
	            	}
	                return null;
	            }
	        });
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 批量获取 Map
	 * @param key 键
	 * @param hashKeys
	 * @return
	 */
	public static List<Object> getMapValuesByPipelined(Object key, List<Object> hashKeys) {
		try {
			return redisTemplate.executePipelined(new RedisCallback<String>() {
	            @Override
	            public String doInRedis(RedisConnection connection) throws DataAccessException {
	            	for (int i = 0; i < hashKeys.size(); i++) {
	                    connection.hGet(key.toString().getBytes(), hashKeys.get(i).toString().getBytes());
	                }
	                return null;
	            }
	        });

		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 批量获取 Map
	 * @param key 键
	 * @param hashKeys
	 * @return
	 */
	public static Map<Object, Object> getMapByPipelined(Object key, List<Object> hashKeys) {
		try {
			Map<Object, Object> result = new HashMap<Object, Object>();
			List<Object> values = getMapValuesByPipelined(key, hashKeys);
			if (!values.isEmpty()) {
				for (int i = 0; i < hashKeys.size(); i++) {
					result.put(hashKeys.get(i), values.get(i));
				}
			}
			return result;
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 获取原字符串 并 重新赋值
	 * @param key 键
	 * @param value 新值
	 * @return
	 */
	public static Object getAndSet(Object key, Object value) {
		try {
			return redisTemplate.opsForValue().getAndSet(key, value);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 在原字符串末尾 追加字符串
	 * @param key 键
	 * @param value 值
	 */
	public static void append(Object key, String value) {
		try {
			redisTemplate.opsForValue().append(key, value);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 存入对象
	 * @param key 键
	 * @param entity 对象
	 */
	public static <T> void setEntity(Object key, T entity) {
		try {
			redisTemplate.opsForValue().set(key, JSONObject.toJSONString(entity));
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 存入对象  并 设置过期时间
	 * @param key 键
	 * @param entity 对象
	 * @param time 时间
	 * @param unit 时间粒度
	 */
	public static <T> void setEntityAndTimeout(Object key, T value, long time, TimeUnit unit) {
		try {
			redisTemplate.opsForValue().set(key, JSONObject.toJSONString(value), time, unit);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 存入对象集合
	 * @param key 键
	 * @param value 集合对象
	 */
	public static <T> void setEntityList(Object key, List<T> entityList) {
		try {
			redisTemplate.opsForValue().set(key, JSONObject.toJSONString(entityList));
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 存入对象集合 并 设置过期时间
	 * @param key 键
	 * @param entityList 对象集合
	 * @param time 时间
	 * @param unit 时间粒度
	 */
	public static <T> void setEntityListAndTimeout(Object key, List<T> entityList, long time, TimeUnit unit) {
		try {
			redisTemplate.opsForValue().set(key, JSONObject.toJSONString(entityList), time, unit);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 获取对象
	 * @param key 键
	 * @return
	 */
	public static <T> T getEntity(Object key, Class<T> clz) {
		try {
			Object obj = redisTemplate.opsForValue().get(key);
			if (obj != null) {
				return jsonToEntity((String) obj, clz);
			}
			return null;
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 获取对象集合
	 * @param key 键
	 * @return
	 */
	public static <T> List<T> getEntityList(Object key, Class<T> clz) {
		try {
			Object obj = redisTemplate.opsForValue().get(key);
			if (obj != null) {
				return jsonToList((String) obj, clz);
			}
			return new ArrayList<T>();
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 获取对象 并 重新赋值
	 * @param key 键
	 * @param newEntity 新对象
	 * @return
	 */
	public static <T> T getEntityAndSet(Object key, T newEntity, Class<T> clz) {
		try {
			Object obj = redisTemplate.opsForValue().getAndSet(key, JSONObject.toJSONString(newEntity));
			if (obj != null) {
				return jsonToEntity((String) obj, clz);
			}
			return null;
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 获取对象集合 并 重新赋值
	 * @param key 键
	 * @param newEntityList 新对象集合
	 * @return
	 */
	public static <T> List<T> getEntityListAndSet(Object key, List<T> newEntityList, Class<T> clz) {
		try {
			Object obj = redisTemplate.opsForValue().getAndSet(key, JSONObject.toJSONString(newEntityList));
			if (obj != null) {
				return jsonToList((String) obj, clz);
			}
			return new ArrayList<T>();
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 转换成 实体类对象
	 * @param text JSON字符串
	 * @param clz 对象的类型
	 * @return
	 */
	public static <T> T jsonToEntity(String text, Class<T> clz) {
		try {
			return JSONArray.parseObject(text, clz);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 转换成 实体类对象集合
	 * @param text JSON字符串
	 * @param clz 对象的类型
	 * @return
	 */
	public static <T> List<T> jsonToList(String text, Class<T> clz) {
		try {
			return JSONArray.parseArray(text, clz);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 对象 转换成 JSON字符串
	 * @param obj
	 * @return
	 */
	public static String toJSONString(Object obj) {
		try {
			return JSONArray.toJSONString(obj);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 判断key是否存在
	 * @param key 键
	 * @return
	 */
	public static Boolean exist(Object key) {
		try {
			return redisTemplate.hasKey(key);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 移除缓存数据
	 * @param key 键
	 */
	public static void delete(Object key) {
		try {
			redisTemplate.delete(key);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 批量移除缓存数据
	 * @param keys 键
	 */
	public static void deleteAll(List<Object> keys) {
		try {
			redisTemplate.delete(keys);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 存入Map
	 * @param key 键
	 * @param hashKey Map的key
	 * @param value Map的value
	 */
	public static void put(Object key, Object hashKey, Object hashValue) {
		try {
			redisTemplate.opsForHash().put(key, hashKey, hashValue);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 不存在便存入Map、存在即存入失败
	 * @param key 键
	 * @param hashKey Map的key
	 * @param value Map的value
	 */
	public static Boolean putIfAbsent(Object key, Object hashKey, Object hashValue) {
		try {
			return redisTemplate.opsForHash().putIfAbsent(key, hashKey, hashValue);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 存入Map
	 * @param key 键
	 * @param map
	 */
	public static void putAll(Object key, Map<? extends Object, ? extends Object> map) {
		try {
			redisTemplate.opsForHash().putAll(key, map);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 批量存入
	 * @param key
	 * @param map
	 * @return
	 */
	public static void putByPipelined(String key, Map<String, String> map) {
		try {
			redisTemplate.executePipelined(new RedisCallback<Object>() {

				@Override
	            public String doInRedis(RedisConnection connection) throws DataAccessException {
					Map<byte[], byte[]> byteMap = new HashMap<byte[], byte[]>();
					for (Entry<String, String> entry : map.entrySet()) {
						byteMap.put(entry.getKey().getBytes(), entry.getValue().getBytes());
					}
					connection.hMSet(key.getBytes(), byteMap);
	                return null;
	            }

	        });
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 获取Map
	 * @param key 键
	 */
	public static Map<Object, Object> getMap(Object key) {
		try {
			return redisTemplate.opsForHash().entries(key);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 获取Map中指定的值
	 * @param key 键
	 * @param hashKey Map的key
	 * @return
	 */
	public static Object getMapValue(Object key, Object hashKey) {
		try {
			return redisTemplate.opsForHash().get(key, hashKey);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 获取Map中所有的key
	 * @param key 键
	 * @return
	 */
	public static Set<Object> getMapKeys(Object key) {
		try {
			return redisTemplate.opsForHash().keys(key);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 获取Map中所有的值
	 * @param key 键
	 * @return
	 */
	public static List<Object> getMapValues(Object key) {
		try {
			return redisTemplate.opsForHash().values(key);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 获取Map的长度
	 * @param key 键
	 * @return
	 */
	public static long getMapSize(Object key) {
		try {
			return redisTemplate.opsForHash().size(key);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 判断Map中key是否存在
	 * @param key 键
	 * @param hashKey Map的key
	 * @return
	 */
	public static Boolean existMapKey(Object key, Object hashKey) {
		try {
			return redisTemplate.opsForHash().hasKey(key, hashKey);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 移除Map中指定的key
	 * @param key 键
	 * @param hashKey Map的key
	 * 单个haskKey 或 数组形式
	 */
	public static void deleteMapKey(Object key, Object... hashKey) {
		try {
			redisTemplate.opsForHash().delete(key, hashKey);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 获取Map中自增数字
	 * @param key 键
	 * @param hashKey Map的key
	 * @param delta 递增的基数
	 * @return
	 */
	public static long getAddNumberForMap(Object key, Object hashKey, long delta) {
		try {
			return redisTemplate.opsForHash().increment(key, hashKey, delta);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 获取自增数字
	 * @param key 键
	 * @param delta 递增的基数
	 * @return
	 */
	public static long getAddNumber(String key, long delta) {
		try {
			RedisAtomicLong counter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
			return counter.addAndGet(delta);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 向左添加元素
	 * @param key 键
	 * @param value 值
	 */
	public static void leftPush(Object key, Object value) {
		try {
			redisTemplate.opsForList().leftPush(key, value);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 向左添加元素-集合
	 * @param key 键
	 * @param values 值(集合)
	 */
	public static void leftPushAll(Object key, Collection<Object> values) {
		try {
			redisTemplate.opsForList().leftPushAll(key, values);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 向右添加元素
	 * @param key 键
	 * @param value 值
	 */
	public static void rightPush(Object key, Object value) {
		try {
			redisTemplate.opsForList().rightPush(key, value);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}
	/**
	 * 向 pivot 右边添加元素
	 * @param key 键
	 * @param pivot 已存在的值
	 * @param value 值
	 */
	public static void rightPush(Object key, Object pivot, Object value) {
		try {
			redisTemplate.opsForList().rightPush(key, pivot, value);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 向右添加元素-集合
	 * @param key 键
	 * @param values 值(集合)
	 */
	public static void rightPushAll(Object key, Collection<Object> values) {
		try {
			redisTemplate.opsForList().rightPushAll(key, values);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 向左弹出元素
	 * @param key 键
	 * @return
	 */
	public static Object leftPop(Object key) {
		try {
			return redisTemplate.opsForList().leftPop(key);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 向右弹出元素
	 * @param key 键
	 * @return
	 */
	public static Object rightPop(Object key) {
		try {
			return redisTemplate.opsForList().rightPop(key);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 将list中的元素截取,并存为新值
	 * @param key
	 * @param start
	 * @param end -1代表全部
	 * @return
	 */
	public static void listTrim(Object key, long start, long end) {
		try {
			redisTemplate.opsForList().trim(key, start, end);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 获取集合长度
	 * @param key 键
	 * @return
	 */
	public static long size(Object key) {
		try {
			return redisTemplate.opsForList().size(key);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 获取集合中指定下标的元素
	 * @param key 键
	 * @param index 下标
	 * @return
	 */
	public static Object index(Object key, long index) {
		try {
			return redisTemplate.opsForList().index(key, index);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 获取指定区间的集合元素
	 * @param key
	 * @param start
	 * @param end
	 * @return
	 */
	public static List<Object> getList(Object key, long start, long end) {
		try {
			return redisTemplate.opsForList().range(key, start, end);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 获取集合元素
	 * @param key
	 * @return
	 */
	public static List<Object> getAllList(Object key) {
		try {
			return redisTemplate.opsForList().range(key, 0, -1);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 集合添加指定下表元素
	 * @param key
	 * @param index
	 * @param value
	 */
	public static void addToList(Object key, int index, Object value) {
		try {
			redisTemplate.opsForList().set(key, index, value);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 删除List中的元素
	 * @param key
	 * @param value
	 */
	public static void removeToList(Object key, Object value) {
		try {
			redisTemplate.opsForList().remove(key, 0, value);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 锁
	 * @param key
	 * @return
	 */
	public static RLock getLock(String key) {
		return redissonClient().getLock(key);
	}

	/* Set */
	/**
	 * 添加Set元素
	 * @param key
	 * @param value 单个或多个...
	 */
	public static void addToSet(Object key, Object value) {
		try {
			redisTemplate.opsForSet().add(key, value);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 获取Set集合
	 * @param key
	 * @return
	 */
	public static Set getToSet(Object key) {
		try {
			return redisTemplate.opsForSet().members(key);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 移除Set中的元素
	 * @param key
	 * @param values
	 */
	public static void deleteToSet(Object key, Object values) {
		try {
			redisTemplate.opsForSet().remove(key, values);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 获取Set长度
	 * @param key
	 * @return
	 */
	public static Long sizeToSet(Object key) {
		try {
			return redisTemplate.opsForSet().size(key);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 添加ZSet元素
	 * @param key
	 * @param value
	 * @param score
	 */
	public static void addToZSet(Object key, Object value, double score) {
		try {
			redisTemplate.opsForZSet().add(key, value, score);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 添加所有ZSet元素
	 * @param key
	 * @param datas key-score 所有元素
	 */
	public static void addToZSetAll(Object key, Map<String, Double> datas) {
		try {
			if (datas != null && !datas.isEmpty()) {
				Set<ZSetOperations.TypedTuple<Object>> tupleDatas = new HashSet<>();
				for (Entry<String, Double> entry : datas.entrySet()) {
					ZSetOperations.TypedTuple<Object> item = new DefaultTypedTuple<>(entry.getKey(), entry.getValue());
					tupleDatas.add(item);
				}
				redisTemplate.opsForZSet().add(key, tupleDatas);
			}
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 合并多个ZSet集合,存入新的集合
	 * @param key 当前集合Key
	 * @param otherKeys 需要合并的即可Keys
	 * @param destKey 合并之后存入的新集合Key
	 */
	public static void unionMoreZSet(Object key, Collection<Object> otherKeys, Object destKey) {
		try {
			redisTemplate.opsForZSet().unionAndStore(key, otherKeys, destKey);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 获取多个ZSet集合的交集,存入新的集合
	 * @param key 当前集合Key
	 * @param otherKeys 需要合并的即可Keys
	 * @param destKey 合并之后存入的新集合Key
	 */
	public static void intersectMoreZSet(Object key, Collection<Object> otherKeys, Object destKey) {
		try {
			redisTemplate.opsForZSet().intersectAndStore(key, otherKeys, destKey);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 获取ZSet长度
	 * @param key
	 */
	public static Long sizeToZSet(Object key) {
		try {
			return redisTemplate.opsForZSet().size(key);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 获取指定区间ZSet集合元素(可用作分页查询)
	 * @param key
	 * @param start
	 * @param end -1代表全部
	 * @return
	 */
	public static Set<Object> getSubZSet(Object key, long start, long end) {
		try {
			return redisTemplate.opsForZSet().range(key, start, end);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 倒序获取指定区间ZSet集合元素(可用作分页查询)
	 * @param key
	 * @param start
	 * @param end -1代表全部
	 * @return
	 */
	public static Set<Object> getSubZSetDesc(Object key, long start, long end) {
		try {
			return redisTemplate.opsForZSet().reverseRange(key, start, end);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 获取ZSet集合元素
	 * @param key
	 * @return
	 */
	public static Set<Object> getAllZSet(Object key) {
		try {
			return redisTemplate.opsForZSet().range(key, 0, -1);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 获取指定分值区间的ZSet集合元素
	 * @param key
	 * @param min
	 * @param max
	 * @return
	 */
	public static Set<Object> getRangeScoreToZSet(Object key, double min, double max) {
		try {
			return redisTemplate.opsForZSet().rangeByScore(key, min, max);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	/**
	 * 获取ZSet集合元素的Score
	 * @param key
	 * @param eo 元素
	 * @return
	 */
	public static double getZSetItemScore(Object key, Object eo) {
		try {
			return redisTemplate.opsForZSet().score(key, eo);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}


	/**
	 * 移除ZSet集合元素
	 * @param key
	 * @return
	 */
	public static void removeToZSet(Object key, Object values) {
		try {
			redisTemplate.opsForZSet().remove(key, values);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}


	/**
	 * 设置key过期时间
	 * @param key
	 * @return
	 */
	public static void setTimeOut(Object key, long timeout, TimeUnit unit) {
		try {
			redisTemplate.expire(key, timeout, unit);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	//#################################################################################
	//#################################################################################
	//##################                    Redis简易版消息队列                                          ##################
	//#################################################################################
	//#################################################################################

	/**
	 * 生成消息
	 * @param channel 频道
	 * @param message 消息对象
	 */
	public static void convertAndSend(String channel, Object message) {
		try {
			redisTemplate.convertAndSend(channel, message);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof RedisConnectionFailureException) {
				throw new SNEBizException(SystemErrorEnum.REDIS_NOT_CONNECTION);
			} else {
				throw new SNEBizException(SystemErrorEnum.REDIS_CACHE_ERROR);
			}
		}
	}

	public static Long increment(String key, Long incr) {
		return redisTemplate.opsForValue().increment(key, incr);
	}

}

2:redis分布式锁

java 复制代码
package com.oceania.b2b.framework.redis.service;

import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RFuture;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Supplier;

/**
 * Redisson 分布式锁工具类(增强版)
 *
 * ✅ 支持 Runnable / Supplier 模板执行
 * ✅ 支持重入标识(当前线程多次加锁)
 * ✅ 支持重试机制(自动尝试获取锁)
 * ✅ 支持异步锁(异步执行任务)
 */
@Slf4j
@Component
public class RedissonDistributedLocker {

    private final RedissonClient redissonClient;

    // 当前线程内已持有的锁 key -> count(用于记录当前线程内是否已经持有某个锁(以及重入次数))
    private final ThreadLocal<Map<String, AtomicInteger>> reentrantLockHolder =
            ThreadLocal.withInitial(ConcurrentHashMap::new);

    public RedissonDistributedLocker(RedissonClient redissonClient) {
        this.redissonClient = redissonClient;
    }

    // ------------------ 基础方法 ------------------

    /**
     * 尝试获取锁(等待 + 自动释放)
     *  1:如果当前线程已持有该锁,则只是递增计数
     *  2:否则调用 Redisson 的 tryLock()。
     *  3:如果获取成功,记录锁信息。
     */
    public boolean tryLock(String key, long waitTime, long leaseTime, TimeUnit unit) {
        try {
            if (isReentrant(key)) {
                incrementReentrant(key);// 支持重入
                return true;
            }

            RLock lock = redissonClient.getLock(key);
            boolean locked = lock.tryLock(waitTime, leaseTime, unit); // 尝试获取锁
            if (locked) {
                incrementReentrant(key);// 成功则计入当前线程
            }
            return locked;
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            log.warn("线程中断,获取锁失败,key={}", key, e);
            return false;
        }
    }

    /**
     * 阻塞加锁(自动释放)
     * 同样支持重入。
     * 若当前线程未持有,则调用 Redisson 的 lock() 方法(阻塞直到成功)。
     */
    public void lock(String key, long leaseTime, TimeUnit unit) {
        if (isReentrant(key)) {
            incrementReentrant(key);
            return;
        }

        RLock lock = redissonClient.getLock(key);
        lock.lock(leaseTime, unit);
        incrementReentrant(key);
    }

    /**
     * 解锁
     * 检查当前线程是否持有该锁(通过 ThreadLocal)
     * 递减锁引用计数,只有降为 0 时才真正执行 unlock()
     */
    public void unlock(String key) {
        if (!isReentrant(key)) {
            return;
        }

        decrementOrRemove(key);
        if (!isReentrant(key)) {
            RLock lock = redissonClient.getLock(key);
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }

    /**
     * 解锁(传入 RLock)
     * 提供更底层的 RLock 解锁接口,用于异步锁释放时调用。
     */
    public void unlock(RLock lock) {
        if (lock != null && lock.isHeldByCurrentThread()) {
            lock.unlock();
        }
    }

    // ------------------ 可重入支持 ------------------

    /**
     * 当前线程是否持有 key 对应的锁
     * @param key
     * @return
     */
    private boolean isReentrant(String key) {
        return reentrantLockHolder.get().containsKey(key);
    }

    /**
     * 加锁时计数 +1
     * @param key
     */
    private void incrementReentrant(String key) {
        reentrantLockHolder.get()
                .computeIfAbsent(key, k -> new AtomicInteger(0))
                .incrementAndGet();
    }

    /**
     *  解锁时计数 -1,归零后移除(释放锁)
     * @param key
     */
    private void decrementOrRemove(String key) {
        Map<String, AtomicInteger> map = reentrantLockHolder.get();
        AtomicInteger counter = map.get(key);
        if (counter != null) {
            if (counter.decrementAndGet() <= 0) {
                map.remove(key);
            }
        }
        if (map.isEmpty()) {
            reentrantLockHolder.remove();
        }
    }

    // ------------------ 执行模板(同步) ------------------

    /**
     * 封装:加锁 + 执行 + 解锁
     * 避免业务层忘记释放锁,提升代码安全性
     * @param key
     * @param leaseTime
     * @param unit
     * @param task
     */
    public void lock(String key, long leaseTime, TimeUnit unit, Runnable task) {
        lock(key, leaseTime, unit);
        try {
            task.run();
        } finally {
            unlock(key);
        }
    }

    /**
     * 加锁执行有返回值的逻辑,适合用于 ID 生成、缓存初始化等
     * @param key
     * @param leaseTime
     * @param unit
     * @param task
     * @return
     * @param <T>
     */
    public <T> T lockAndReturn(String key, long leaseTime, TimeUnit unit, Supplier<T> task) {
        lock(key, leaseTime, unit);
        try {
            return task.get();
        } finally {
            unlock(key);
        }
    }

    // ------------------ 支持重试机制 ------------------

    public boolean tryLockWithRetry(String key, long leaseTime, long totalWaitTime, long retryInterval, TimeUnit unit) {
        long deadline = System.currentTimeMillis() + unit.toMillis(totalWaitTime);
        while (System.currentTimeMillis() < deadline) {
            if (tryLock(key, 0, leaseTime, unit)) {
                return true;
            }
            try {
                Thread.sleep(unit.toMillis(retryInterval));
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                break;
            }
        }
        return false;
    }

    /**
     * 若初次未获取锁,可自动等待重试
     * 常用于不想立刻失败的场景,如资源初始化、消息消费
     * @param key
     * @param leaseTime
     * @param totalWaitTime
     * @param retryInterval
     * @param unit
     * @return
     */
    public void tryLockWithRetry(String key, long leaseTime, long totalWaitTime, long retryInterval, TimeUnit unit, Runnable task) {
        boolean locked = tryLockWithRetry(key, leaseTime, totalWaitTime, retryInterval, unit);
        if (!locked) {
            throw new RuntimeException("无法获取锁: " + key);
        }
        try {
            task.run();
        } finally {
            unlock(key);
        }
    }

    // ------------------ 异步锁支持 ------------------

    /**
     * Redisson 的异步锁封装
     * 用于异步任务执行时保护共享资源(非阻塞)
     * @param key
     * @param leaseTime
     * @param unit
     * @param task
     * @return
     */
    public CompletableFuture<Void> lockAsync(String key, long leaseTime, TimeUnit unit, Runnable task) {
        RLock lock = redissonClient.getLock(key);
        RFuture<Void> future = lock.lockAsync(leaseTime, unit);
        return future.toCompletableFuture()
                .thenRunAsync(() -> {
                    try {
                        task.run();
                    } finally {
                        unlock(lock);
                    }
                });
    }

    public <T> CompletableFuture<T> lockAsync(String key, long leaseTime, TimeUnit unit, Supplier<T> supplier) {
        RLock lock = redissonClient.getLock(key);
        RFuture<Void> future = lock.lockAsync(leaseTime, unit);
        return future.toCompletableFuture()
                .thenApplyAsync(ignored -> {
                    try {
                        return supplier.get();
                    } finally {
                        unlock(lock);
                    }
                });
    }
}
相关推荐
ZWZhangYu1 小时前
LangChain 构建向量数据库和检索器
数据库·langchain·easyui
feifeigo1232 小时前
升级到MySQL 8.4,MySQL启动报错:io_setup() failed with EAGAIN
数据库·mysql·adb
weixin_446122463 小时前
JAVA内存区域划分
java·开发语言·redis
火龙谷4 小时前
【nosql】有哪些非关系型数据库?
数据库·nosql
TT哇4 小时前
JavaEE==网站开发
java·redis·java-ee
焱焱枫4 小时前
Oracle获取执行计划之10046 技术详解
数据库·oracle
一只叫煤球的猫7 小时前
真实事故复盘:Redis分布式锁居然失效了?公司十年老程序员踩的坑
java·redis·后端
一只fish8 小时前
MySQL 8.0 OCP 1Z0-908 题目解析(17)
数据库·mysql
花好月圆春祺夏安8 小时前
基于odoo17的设计模式详解---装饰模式
数据库·python·设计模式