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);
                    }
                });
    }
}
相关推荐
····懂···12 分钟前
开源数据库PostgreSQL专家技术
数据库·postgresql·开源
NUZGNAW19 分钟前
Ubuntu 安装redis和nginx
redis·nginx·ubuntu
Asu520221 分钟前
思途SQL学习 0729
数据库·sql·学习
北亚数据恢复38 分钟前
服务器数据恢复—RAID上层部署的oracle数据库数据恢复案例
数据库·oracle·服务器数据恢复·北亚数据恢复
不辉放弃1 小时前
kafka的消息存储机制和查询机制
数据库·kafka·pyspark·大数据开发
ZZH1120KQ3 小时前
ORACLE的用户维护与权限操作
数据库·oracle
妮妮喔妮3 小时前
图片上传 el+node后端+数据库
javascript·数据库·vue.js
仰望星空的凡人8 小时前
【JS逆向基础】数据库之MongoDB
javascript·数据库·python·mongodb
duration~10 小时前
PostgreSQL并发控制
数据库·postgresql
给力学长11 小时前
自习室预约小程序的设计与实现
java·数据库·vue.js·elementui·小程序·uni-app·node.js