Pu Zhibing
昨天 c3b7673c16d026e57f8759b4cee99a42bf3c57f2
UserZYTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/RedisUtil.java
@@ -1,23 +1,23 @@
package com.stylefeng.guns.modular.system.util;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.stylefeng.guns.core.util.ToolUtil;
import org.apache.tomcat.util.threads.ThreadPoolExecutor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.data.geo.Circle;
import org.springframework.data.geo.GeoResult;
import org.springframework.data.geo.GeoResults;
import org.springframework.data.geo.Point;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Pipeline;
import java.io.IOException;
import javax.annotation.PostConstruct;
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
@@ -27,11 +27,10 @@
public class RedisUtil {
    
    @Autowired
    private JedisPool jedisPool;
    private Timer timer;
    private RedisTemplate redisTemplate;
    private final Map<String, ScheduledExecutorService> LOCK_TASK_MAP = new HashMap<>();
    /**
     * 向redis中存储字符串没有过期时间
     * @param key
@@ -39,9 +38,7 @@
     */
    public void setStrValue(String key, String value){
        if(ToolUtil.isNotEmpty(key) && ToolUtil.isNotEmpty(value)){
            Jedis resource = jedisPool.getResource();
            String set = resource.set(key, value);
            closeJedis(resource);
            redisTemplate.opsForValue().set(key, value);
        }
    }
    
@@ -54,9 +51,7 @@
     */
    public void setStrValue(String key, String value, int time){
        if(ToolUtil.isNotEmpty(key) && ToolUtil.isNotEmpty(value)){
            Jedis resource = jedisPool.getResource();
            String setex = resource.setex(key, time, value);
            closeJedis(resource);
            redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
        }
    }
    
@@ -68,46 +63,15 @@
     */
    public String getValue(String key){
        if(ToolUtil.isNotEmpty(key)){
            Jedis resource = jedisPool.getResource();
            String data = resource.get(key);
            closeJedis(resource);
            return data;
            System.err.println("查询缓存:" + key);
            Object o = redisTemplate.opsForValue().get(key);
            System.err.println(o);
            return (String) o;
        }
        return null;
    }
    
    /**
     * 批量获取
     * @param kes
     * @return
     */
    public List<Object> getValues(List<String> kes){
        if(null != kes){
            Jedis resource = jedisPool.getResource();
            Pipeline pipelined = resource.pipelined();
            for(String key : kes){
                pipelined.get(key);
            }
            List<Object> list = pipelined.syncAndReturnAll();
            closeJedis(resource);
            pipelined.clear();
            try {
                pipelined.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            List<Object> data = new ArrayList<>();
            for(Object o : list){
                if(null != o){
                    data.add(o);
                }
            }
            return data;
        }
        return null;
    }
    
    
    /**
@@ -116,138 +80,113 @@
     */
    public void remove(String key){
        if(ToolUtil.isNotEmpty(key)){
            Jedis resource = jedisPool.getResource();
            Long del = resource.del(key);
            closeJedis(resource);
            redisTemplate.delete(key);
        }
    }
    /**
     * 向集合key添加数据
     * 加锁
     * @param key
     * @param members
     */
    public void addSetValue(String key, String...members){
        if(ToolUtil.isNotEmpty(key) && ToolUtil.isNotEmpty(members)){
            Jedis resource = jedisPool.getResource();
            Long sadd = resource.sadd(key, members);
            resource.close();
        }
    }
    /**
     * 返回Set集合数据
     * @param key
     * @return
     */
    public Set<String> getSetAllValue(String key){
        Set<String> smembers = new HashSet<>();
        if(ToolUtil.isNotEmpty(key)){
            Jedis resource = jedisPool.getResource();
            smembers = resource.smembers(key);
            resource.close();
        }
        return smembers;
    }
    /**
     * 删除Set集合中的值
     * @param key
     * @param members
     */
    public void delSetValue(String key, String...members){
        if(ToolUtil.isNotEmpty(key) && ToolUtil.isNotEmpty(members)){
            Jedis resource = jedisPool.getResource();
            Long sadd = resource.srem(key, members);
            resource.close();
        }
    }
    /**
     * 删除资源
     * @param jedis
     */
    public void closeJedis(Jedis jedis){
        if(null != jedis){
            jedis.close();
        }
    }
    /**
     * redis加锁
     * @param key
     * @param value
     * @param time
     * @return
     */
    public boolean lock(String key, String value, int time){
        if(!StringUtils.isEmpty(key)){
            key += "_lock";
            Jedis resource = jedisPool.getResource();
            String set = resource.set(key, value, "nx", "ex", time);
            if("OK".equals(set)){
                String finalKey = key;
                timer = new Timer();
                timer.schedule(new TimerTask() {
                    @Override
                    public void run() {
                        System.err.println("定时任务启动");
                        Jedis resource = jedisPool.getResource();
                        resource.setex(finalKey, time, value);
                        resource.close();
                    }
                }, 1000, 500);
    public boolean lock(String key, long keepTime, long time){
        ScheduledExecutorService scheduledExecutorService = LOCK_TASK_MAP.get(key);
        if(null == scheduledExecutorService || scheduledExecutorService.isTerminated()){
            unlock(key);
        }
        keepTime *= 1000;
        Boolean ifAbsent = redisTemplate.opsForValue().setIfAbsent(key, UUIDUtil.getRandomCode());
        if(ifAbsent){
            return addLockMap(key, time);
        }
        long timeMillis = System.currentTimeMillis();
        while (timeMillis + keepTime > System.currentTimeMillis()){
            ifAbsent = redisTemplate.opsForValue().setIfAbsent(key, UUIDUtil.getRandomCode());
            if(ifAbsent){
                return addLockMap(key, time);
            }
            resource.close();
            return "OK".equals(set) ? true : false;
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return false;
    }
    /**
     * 获取redis锁
     * @param time
     * @return
     */
    public boolean lock(int time){
        String uuid = UUID.randomUUID().toString();
        return lock("redis", uuid, time);
    private boolean addLockMap(String key, long time){
        ScheduledExecutorService scheduledExecutorService = LOCK_TASK_MAP.get(key);
        if(null == scheduledExecutorService){
            scheduledExecutorService = Executors.newScheduledThreadPool(1);
        }
        LOCK_TASK_MAP.put(key, scheduledExecutorService);
        scheduledExecutorService.schedule(()->{
            redisTemplate.delete(key);
            LOCK_TASK_MAP.remove(key);
        }, time, TimeUnit.SECONDS);
        return true;
    }
    public boolean lock(String key, int time){
        String uuid = UUID.randomUUID().toString();
        return lock(key, uuid, time);
    }
    
    /**
     * redis释放锁
     * @param key
     * @return
     */
    public boolean unlock(String key){
        if(!StringUtils.isEmpty(key)){
            key += "_lock";
            Jedis resource = jedisPool.getResource();
            timer.cancel();//取消定时任务
            Long del = resource.del(key);
            resource.close();
            return del != 0 ? true : false;
        redisTemplate.delete(key);
        ScheduledExecutorService scheduledExecutorService = LOCK_TASK_MAP.get(key);
        if(null != scheduledExecutorService){
            scheduledExecutorService.shutdownNow();
        }
        return false;
        LOCK_TASK_MAP.remove(key);
        return true;
    }
    /**
     * 删除锁
     * 检索坐标为中心直径范围内的数据,单位米
     * @param k
     * @param lon
     * @param lat
     * @param radius
     * @return
     */
    public boolean unlock(){
        return unlock("redis");
    public List<GeoResult<RedisGeoCommands.GeoLocation<String>>> getNearGeo(String k, Double lon, Double lat, Double radius){
        Circle within = new Circle(lon, lat, radius);
        GeoResults<RedisGeoCommands.GeoLocation<String>> geoResults = redisTemplate.opsForGeo().radius(k, within);
        return geoResults.getContent();
    }
    /**
     * 检索坐标为中心直径范围内的数据,单位米,由近到远排序
     * @param k
     * @param lon
     * @param lat
     * @param radius
     * @return
     */
    public List<GeoResult<RedisGeoCommands.GeoLocation<String>>> getNearGeoSortAscending(String k, Double lon, Double lat, Double radius){
        Circle within = new Circle(lon, lat, radius);
        RedisGeoCommands.GeoRadiusCommandArgs geoRadiusCommandArgs = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs();
        geoRadiusCommandArgs.sortAscending();
        GeoResults<RedisGeoCommands.GeoLocation<String>> geoResults = redisTemplate.opsForGeo().radius(k, within, geoRadiusCommandArgs);
        return geoResults.getContent();
    }
    /**
     * 添加地理空间索引坐标
     * @param k
     * @param lon
     * @param lat
     * @param object
     */
    public void addGeo(String k, Double lon, Double lat, String object){
        Point point = new Point(lon, lat);
        redisTemplate.opsForGeo().add(k, point, object);
    }
}