spring boot整合redis,以及设置缓存过期时间

spring-boot 整合 redis,有问题,欢迎留言

注:redis服务器要先开启! 或者连接远程服务器上的 Redis,但是依然要开启服务,不然会一直 TimeOut!

pom文件:

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
配置 application.properties
# redis
# Redis数据库索引(默认为0)
spring.redis.database=0
# Redis服务器地址
spring.redis.host=localhost
# Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
spring.redis.password=
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.jedis.pool.max-active=20
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedis.pool.max-wait=-1
# 连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle=10
# 连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle=0
# 连接超时时间(毫秒)
spring.redis.timeout=1000

配置文件写完之后基础环境也算是已经搭建好了,开始测试使用 Test

接下来  我们测试上代码:

    //注入redisTemplate
    @Autowired
    private StringRedisTemplate redisTemplate;

    @Test
    public void setRedis() {
     //缓存中最常用的方法 redisTemplate.opsForValue().set(
"first","siwei");
     //设置缓存过期时间为30 单位:秒
     //关于TimeUnit下面有部分源码截图 redisTemplate.opsForValue().set(
"second","siweiWu",30, TimeUnit.SECONDS); System.out.println("存入缓存成功"); } @Test public void getRedis(){ String first = redisTemplate.opsForValue().get("first"); String second = redisTemplate.opsForValue().get("second"); System.out.println("取出缓存中first的数据是:"+first); System.out.println("取出缓存中second的数据是:"+second); } @Test public void delRedis() { //根据key删除缓存 Boolean first1 = redisTemplate.delete("first"); System.out.println("是否删除成功:"+first1); }

附上日常项目中使用的服务层的 Redis 五种(String,Hash,List,Set,ZSet)常用的方法,可以直接拷贝使用,自行导包噢~

创建 RedisService 服务类
import org.springframework.data.redis.core.ListOperations;

import java.util.List;
import java.util.Set;


/**
* @author wusw
* @date 2020/4/16 13:11
*/
public interface RedisService {


    /**
     * 添加 key:string 缓存
     *
     * @param key    key
     * @param value    value
     * @param time time
     * @return
     */
    boolean cacheValue(String key, String value, long time);


    /**
     * 添加 key:string 缓存
     *
     * @param key   key
     * @param value value
     * @return
     */
    boolean cacheValue(String key, String value);


    /**
     * 根据 key:string 判断缓存是否存在
     *
     * @param key key
     * @return boolean
     */
    boolean containsValueKey(String key);


    /**
     * 判断缓存 key:set集合 是否存在
     *
     * @param key key
     * @return
     */
    boolean containsSetKey(String key);


    /**
     * 判断缓存 key:list集合 是否存在
     *
     * @param key key
     * @return boolean
     */
    boolean containsListKey(String key);


    /**
     * 查询缓存 key 是否存在
     * @param key key
     * @return true/false
     */
    boolean containsKey(String key);


    /**
     * 根据 key 获取缓存value
     *
     * @param key key
     * @return value
     */
    String getValue(String key);


    /**
     * 根据 key 移除 value 缓存
     *
     * @param key key
     * @return true/false
     */
    boolean removeValue(String key);


    /**
     * 根据 key 移除 set 缓存
     *
     * @param key key
     * @return true/false
     */
    boolean removeSet(String key);


    /**
     * 根据 key 移除 list 缓存
     *
     * @param key key
     * @return true/false
     */
    boolean removeList(String key);


    /**
     * 缓存set操作
     *
     * @param key    key
     * @param value    value
     * @param time time
     * @return boolean
     */
    boolean cacheSet(String key, String value, long time);


    /**
     * 添加 set 缓存
     *
     * @param key   key
     * @param value value
     * @return true/false
     */
    boolean cacheSet(String key, String value);


    /**
     * 添加 缓存 set
     *
     * @param k    key
     * @param v    value
     * @param time 时间
     * @return
     */
    boolean cacheSet(String k, Set<String> v, long time);


    /**
     * 缓存 set
     * @param k key
     * @param v value
     * @return
     */
    boolean cacheSet(String k, Set<String> v);


    /**
     * 获取缓存set数据
     * @param k key
     * @return set集合
     */
    Set<String> getSet(String k);


    /**
     * list 缓存
     * @param k key
     * @param v value
     * @param time 时间
     * @return true/false
     */
    boolean cacheList(String k, String v, long time);


    /**
     * 缓存 list
     * @param k key
     * @param v value
     * @return true/false
     */
    boolean cacheList(String k, String v);


    /**
     * 缓存 list 集合
     * @param k key
     * @param v value
     * @param time 时间
     * @return
     */
    boolean cacheList(String k, List<String> v, long time);


    /**
     *  缓存 list
     * @param k key
     * @param v value
     * @return true/false
     */
    boolean cacheList(String k, List<String> v);


    /**
     * 根据 key 获取 list 缓存
     * @param k key
     * @param start 开始
     * @param end 结束
     * @return 获取缓存区间内 所有value
     */
    List<String> getList(String k, long start, long end);


    /**
     * 根据 key 获取总条数 用于分页
     * @param key key
     * @return 条数
     */
    long getListSize(String key);


    /**
     * 获取总条数 用于分页
     * @param listOps =redisTemplate.opsForList();
     * @param k key
     * @return size
     */
    long getListSize(ListOperations<String, String> listOps, String k);


    /**
     * 根据 key 移除 list 缓存
     * @param k key
     * @return
     */
    boolean removeOneOfList(String k);
}
RedisService

创建 RedisServiceImpl 实现 RedisService 接口

import com.technologies.bear.service.RedisService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;


/**
* @author wusw
* @date 2020/4/16 13:11
*/
@Service
public class RedisServiceImpl implements RedisService {
    /**
     * slf4j 日志
     */
    private final Logger log = LoggerFactory.getLogger(this.getClass());


    /**
     * 自定义 key 三种
     *  String key:String value         普通key:value
     *  String key:Set<String> set      key:set集合
     *  String key:List<String> list    key:list集合
     */
    private static final String KEY_PREFIX_KEY = "info:bear:key";
    private static final String KEY_PREFIX_SET = "info:bear:set";
    private static final String KEY_PREFIX_LIST = "info:bear:list";


    private final RedisTemplate<String, String> redisTemplate;


    /**
     * 注入
     * @param redisTemplate 模板
     */
    @Autowired
    public RedisServiceImpl(RedisTemplate<String, String> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }


    /**
     * 添加 key:string 缓存
     *
     * @param k    key
     * @param v    value
     * @param time time
     * @return
     */
    @Override
    public boolean cacheValue(String k, String v, long time) {
        try {
            String key = KEY_PREFIX_KEY + k;
            ValueOperations<String, String> ops = redisTemplate.opsForValue();
            ops.set(key, v);
            if (time > 0) {
                redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Throwable e) {
            log.error("缓存存入失败key:[{}] value:[{}]", k, v);
        }
        return false;
    }


    /**
     * 添加 key:string 缓存
     *
     * @param key   key
     * @param value value
     * @return
     */
    @Override
    public boolean cacheValue(String key, String value) {
        return cacheValue(key, value, -1);
    }


    /**
     * 根据 key:string 判断缓存是否存在
     *
     * @param key key
     * @return boolean
     */
    @Override
    public boolean containsValueKey(String key) {
        return containsKey(KEY_PREFIX_KEY + key);
    }


    /**
     * 判断缓存 key:set集合 是否存在
     *
     * @param key key
     * @return
     */
    @Override
    public boolean containsSetKey(String key) {
        return containsKey(KEY_PREFIX_SET + key);
    }


    /**
     * 判断缓存 key:list集合 是否存在
     *
     * @param key key
     * @return boolean
     */
    @Override
    public boolean containsListKey(String key) {
        return containsKey(KEY_PREFIX_LIST + key);
    }


    /**
     * 查询缓存 key 是否存在
     * @param key key
     * @return true/false
     */
    @Override
    public boolean containsKey(String key) {
        try {
            return redisTemplate.hasKey(key);
        } catch (Throwable e) {
            log.error("判断缓存存在失败key:[" + key + "],错误信息 Codeor[{}]", e);
        }
        return false;
    }


    /**
     * 根据 key 获取缓存value
     *
     * @param key key
     * @return value
     */
    @Override
    public String getValue(String key) {
        try {
            ValueOperations<String, String> ops = redisTemplate.opsForValue();
            return ops.get(KEY_PREFIX_KEY + key);
        } catch (Throwable e) {
            log.error("根据 key 获取缓存失败,当前key:[{}],失败原因 Codeor:[{}]", key, e);
        }
        return null;
    }


    /**
     * 缓存set操作
     *
     * @param k    key
     * @param v    value
     * @param time time
     * @return boolean
     */
    @Override
    public boolean cacheSet(String k, String v, long time) {
        try {
            String key = KEY_PREFIX_SET + k;
            SetOperations<String, String> opsForSet = redisTemplate.opsForSet();
            opsForSet.add(key, v);
            if (time > 0) {
                redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Throwable e) {
            log.error("缓存 set 失败 当前 key:[{}] 失败原因 [{}]", k, e);
        }
        return false;
    }


    /**
     * 添加 set 缓存
     *
     * @param key   key
     * @param value value
     * @return true/false
     */
    @Override
    public boolean cacheSet(String key, String value) {
        return cacheSet(key, value, -1);
    }


    /**
     * 添加 缓存 set
     *
     * @param k    key
     * @param v    value
     * @param time 时间
     * @return
     */
    @Override
    public boolean cacheSet(String k, Set<String> v, long time) {
        try {
            String key = KEY_PREFIX_SET + k;
            SetOperations<String, String> opsForSet = redisTemplate.opsForSet();
            opsForSet.add(key, v.toArray(new String[v.size()]));
            if (time > 0){
                redisTemplate.expire(key,time,TimeUnit.SECONDS);
            }
            return true;
        } catch (Throwable e) {
            log.error("缓存 set 失败 当前 key:[{}],失败原因 [{}]", k, e);
        }
        return false;
    }


    /**
     * 缓存 set
     * @param k key
     * @param v value
     * @return
     */
    @Override
    public boolean cacheSet(String k, Set<String> v) {
        return cacheSet(k,v,-1);
    }


    /**
     * 获取缓存set数据
     * @param k key
     * @return set集合
     */
    @Override
    public Set<String> getSet(String k) {
        try {
            String key = KEY_PREFIX_SET + k;
            SetOperations<String, String> opsForSet = redisTemplate.opsForSet();
            return opsForSet.members(key);
        }catch (Throwable e){
            log.error("获取缓存set失败 当前 key:[{}],失败原因 [{}]", k, e);
        }
        return null;
    }


    /**
     * list 缓存
     * @param k key
     * @param v value
     * @param time 时间
     * @return true/false
     */
    @Override
    public boolean cacheList(String k, String v, long time) {
        try {
            String key = KEY_PREFIX_LIST + k;
            ListOperations<String, String> opsForList = redisTemplate.opsForList();
            //此处为right push 方法/ 也可以 left push ..
            opsForList.rightPush(key,v);
            if (time > 0){
                redisTemplate.expire(key,time,TimeUnit.SECONDS);
            }
            return true;
        }catch (Throwable e){
            log.error("缓存list失败 当前 key:[{}],失败原因 [{}]", k, e);
        }
        return false;
    }


    /**
     * 缓存 list
     * @param k key
     * @param v value
     * @return true/false
     */
    @Override
    public boolean cacheList(String k, String v) {
        return cacheList(k,v,-1);
    }


    /**
     * 缓存 list 集合
     * @param k key
     * @param v value
     * @param time 时间
     * @return
     */
    @Override
    public boolean cacheList(String k, List<String> v, long time) {
        try {
            String key = KEY_PREFIX_LIST + k;
            ListOperations<String, String> opsForList = redisTemplate.opsForList();
            opsForList.rightPushAll(key,v);
            if (time > 0){
                redisTemplate.expire(key,time,TimeUnit.SECONDS);
            }
            return true;
        }catch (Throwable e){
            log.error("缓存list失败 当前 key:[{}],失败原因 [{}]", k, e);
        }
        return false;
    }


    /**
     *  缓存 list
     * @param k key
     * @param v value
     * @return true/false
     */
    @Override
    public boolean cacheList(String k, List<String> v) {
        return cacheList(k,v,-1);
    }


    /**
     * 根据 key 获取 list 缓存
     * @param k key
     * @param start 开始
     * @param end 结束
     * @return 获取缓存区间内 所有value
     */
    @Override
    public List<String> getList(String k, long start, long end) {
        try {
            String key = KEY_PREFIX_LIST + k;
            ListOperations<String, String> opsForList = redisTemplate.opsForList();
            return opsForList.range(key,start,end);
        }catch (Throwable e){
            log.error("获取list缓存失败 当前 key:[{}],失败原因 [{}]", k, e);
        }
        return null;
    }


    /**
     * 根据 key 获取总条数 用于分页
     * @param key key
     * @return 条数
     */
    @Override
    public long getListSize(String key) {
        try {
            ListOperations<String, String> opsForList = redisTemplate.opsForList();
            return opsForList.size(KEY_PREFIX_LIST + key);
        }catch (Throwable e){
            log.error("获取list长度失败key[" + KEY_PREFIX_LIST + key + "], Codeor[" + e + "]");
        }
        return 0;
    }


    /**
     * 获取总条数 用于分页
     * @param listOps =redisTemplate.opsForList();
     * @param k key
     * @return size
     */
    @Override
    public long getListSize(ListOperations<String, String> listOps, String k) {
        try {
            return listOps.size(k);
        }catch (Throwable e){
            log.error("获取list长度失败key[" + KEY_PREFIX_LIST + k + "], Codeor[" + e + "]");
        }
        return 0;
    }


    /**
     * 根据 key 移除 list 缓存
     * @param k key
     * @return
     */
    @Override
    public boolean removeOneOfList(String k) {
        try {
            String key = KEY_PREFIX_LIST + k;
            ListOperations<String, String> opsForList = redisTemplate.opsForList();
            opsForList.rightPop(key);
            return true;
        }catch (Throwable e){
            log.error("移除list缓存失败 key[" + KEY_PREFIX_LIST + k + "], Codeor[" + e + "]");
        }
        return false;
    }


    /**
     * 根据 key 移除 value 缓存
     *
     * @param key key
     * @return true/false
     */
    @Override
    public boolean removeValue(String key) {
        return remove(KEY_PREFIX_KEY + key);
    }


    /**
     * 根据 key 移除 set 缓存
     *
     * @param key key
     * @return true/false
     */
    @Override
    public boolean removeSet(String key) {
        return remove(KEY_PREFIX_SET + key);
    }


    /**
     * 根据 key 移除 list 缓存
     *
     * @param key key
     * @return true/false
     */
    @Override
    public boolean removeList(String key) {
        return remove(KEY_PREFIX_LIST + key);
    }


    /**
     * 移除缓存
     *
     * @param key key
     * @return boolean
     */
    private boolean remove(String key) {
        try {
            redisTemplate.delete(key);
            return true;
        } catch (Throwable e) {
            log.error("移除缓存失败 key:[{}] 失败原因 [{}]", key, e);
        }
        return false;
    }
}
RedisServiceImpl

 注:其他 Service 层使用时,只需要将 RedisService 注入即可像普通Service层一样调用

StringRedisTemplate相关方法我也总结了一下,可能不是很全  不过还是够用了

上面设置缓存过期时间的TimeUnit源码 部分截图说明(后面会附上全部的源码——总390行,我就折叠一下了):

先上截图

TimeUnit全部源码:

  1 /*
  2  * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  3  *
  4  *
  5  *
  6  *
  7  *
  8  *
  9  *
 10  *
 11  *
 12  *
 13  *
 14  *
 15  *
 16  *
 17  *
 18  *
 19  *
 20  *
 21  *
 22  *
 23  */
 24 
 25 /*
 26  *
 27  *
 28  *
 29  *
 30  *
 31  * Written by Doug Lea with assistance from members of JCP JSR-166
 32  * Expert Group and released to the public domain, as explained at
 33  * http://creativecommons.org/publicdomain/zero/1.0/
 34  */
 35 
 36 package java.util.concurrent;
 37 
 38 /**
 39  * A {@code TimeUnit} represents time durations at a given unit of
 40  * granularity and provides utility methods to convert across units,
 41  * and to perform timing and delay operations in these units.  A
 42  * {@code TimeUnit} does not maintain time information, but only
 43  * helps organize and use time representations that may be maintained
 44  * separately across various contexts.  A nanosecond is defined as one
 45  * thousandth of a microsecond, a microsecond as one thousandth of a
 46  * millisecond, a millisecond as one thousandth of a second, a minute
 47  * as sixty seconds, an hour as sixty minutes, and a day as twenty four
 48  * hours.
 49  *
 50  * <p>A {@code TimeUnit} is mainly used to inform time-based methods
 51  * how a given timing parameter should be interpreted. For example,
 52  * the following code will timeout in 50 milliseconds if the {@link
 53  * java.util.concurrent.locks.Lock lock} is not available:
 54  *
 55  *  <pre> {@code
 56  * Lock lock = ...;
 57  * if (lock.tryLock(50L, TimeUnit.MILLISECONDS)) ...}</pre>
 58  *
 59  * while this code will timeout in 50 seconds:
 60  *  <pre> {@code
 61  * Lock lock = ...;
 62  * if (lock.tryLock(50L, TimeUnit.SECONDS)) ...}</pre>
 63  *
 64  * Note however, that there is no guarantee that a particular timeout
 65  * implementation will be able to notice the passage of time at the
 66  * same granularity as the given {@code TimeUnit}.
 67  *
 68  * @since 1.5
 69  * @author Doug Lea
 70  */
 71 public enum TimeUnit {
 72     /**
 73      * Time unit representing one thousandth of a microsecond
 74      */
 75     NANOSECONDS {
 76         public long toNanos(long d)   { return d; }
 77         public long toMicros(long d)  { return d/(C1/C0); }
 78         public long toMillis(long d)  { return d/(C2/C0); }
 79         public long toSeconds(long d) { return d/(C3/C0); }
 80         public long toMinutes(long d) { return d/(C4/C0); }
 81         public long toHours(long d)   { return d/(C5/C0); }
 82         public long toDays(long d)    { return d/(C6/C0); }
 83         public long convert(long d, TimeUnit u) { return u.toNanos(d); }
 84         int excessNanos(long d, long m) { return (int)(d - (m*C2)); }
 85     },
 86 
 87     /**
 88      * Time unit representing one thousandth of a millisecond
 89      */
 90     MICROSECONDS {
 91         public long toNanos(long d)   { return x(d, C1/C0, MAX/(C1/C0)); }
 92         public long toMicros(long d)  { return d; }
 93         public long toMillis(long d)  { return d/(C2/C1); }
 94         public long toSeconds(long d) { return d/(C3/C1); }
 95         public long toMinutes(long d) { return d/(C4/C1); }
 96         public long toHours(long d)   { return d/(C5/C1); }
 97         public long toDays(long d)    { return d/(C6/C1); }
 98         public long convert(long d, TimeUnit u) { return u.toMicros(d); }
 99         int excessNanos(long d, long m) { return (int)((d*C1) - (m*C2)); }
100     },
101 
102     /**
103      * Time unit representing one thousandth of a second
104      */
105     MILLISECONDS {
106         public long toNanos(long d)   { return x(d, C2/C0, MAX/(C2/C0)); }
107         public long toMicros(long d)  { return x(d, C2/C1, MAX/(C2/C1)); }
108         public long toMillis(long d)  { return d; }
109         public long toSeconds(long d) { return d/(C3/C2); }
110         public long toMinutes(long d) { return d/(C4/C2); }
111         public long toHours(long d)   { return d/(C5/C2); }
112         public long toDays(long d)    { return d/(C6/C2); }
113         public long convert(long d, TimeUnit u) { return u.toMillis(d); }
114         int excessNanos(long d, long m) { return 0; }
115     },
116 
117     /**
118      * Time unit representing one second
119      */
120     SECONDS {
121         public long toNanos(long d)   { return x(d, C3/C0, MAX/(C3/C0)); }
122         public long toMicros(long d)  { return x(d, C3/C1, MAX/(C3/C1)); }
123         public long toMillis(long d)  { return x(d, C3/C2, MAX/(C3/C2)); }
124         public long toSeconds(long d) { return d; }
125         public long toMinutes(long d) { return d/(C4/C3); }
126         public long toHours(long d)   { return d/(C5/C3); }
127         public long toDays(long d)    { return d/(C6/C3); }
128         public long convert(long d, TimeUnit u) { return u.toSeconds(d); }
129         int excessNanos(long d, long m) { return 0; }
130     },
131 
132     /**
133      * Time unit representing sixty seconds
134      */
135     MINUTES {
136         public long toNanos(long d)   { return x(d, C4/C0, MAX/(C4/C0)); }
137         public long toMicros(long d)  { return x(d, C4/C1, MAX/(C4/C1)); }
138         public long toMillis(long d)  { return x(d, C4/C2, MAX/(C4/C2)); }
139         public long toSeconds(long d) { return x(d, C4/C3, MAX/(C4/C3)); }
140         public long toMinutes(long d) { return d; }
141         public long toHours(long d)   { return d/(C5/C4); }
142         public long toDays(long d)    { return d/(C6/C4); }
143         public long convert(long d, TimeUnit u) { return u.toMinutes(d); }
144         int excessNanos(long d, long m) { return 0; }
145     },
146 
147     /**
148      * Time unit representing sixty minutes
149      */
150     HOURS {
151         public long toNanos(long d)   { return x(d, C5/C0, MAX/(C5/C0)); }
152         public long toMicros(long d)  { return x(d, C5/C1, MAX/(C5/C1)); }
153         public long toMillis(long d)  { return x(d, C5/C2, MAX/(C5/C2)); }
154         public long toSeconds(long d) { return x(d, C5/C3, MAX/(C5/C3)); }
155         public long toMinutes(long d) { return x(d, C5/C4, MAX/(C5/C4)); }
156         public long toHours(long d)   { return d; }
157         public long toDays(long d)    { return d/(C6/C5); }
158         public long convert(long d, TimeUnit u) { return u.toHours(d); }
159         int excessNanos(long d, long m) { return 0; }
160     },
161 
162     /**
163      * Time unit representing twenty four hours
164      */
165     DAYS {
166         public long toNanos(long d)   { return x(d, C6/C0, MAX/(C6/C0)); }
167         public long toMicros(long d)  { return x(d, C6/C1, MAX/(C6/C1)); }
168         public long toMillis(long d)  { return x(d, C6/C2, MAX/(C6/C2)); }
169         public long toSeconds(long d) { return x(d, C6/C3, MAX/(C6/C3)); }
170         public long toMinutes(long d) { return x(d, C6/C4, MAX/(C6/C4)); }
171         public long toHours(long d)   { return x(d, C6/C5, MAX/(C6/C5)); }
172         public long toDays(long d)    { return d; }
173         public long convert(long d, TimeUnit u) { return u.toDays(d); }
174         int excessNanos(long d, long m) { return 0; }
175     };
176 
177     // Handy constants for conversion methods
178     static final long C0 = 1L;
179     static final long C1 = C0 * 1000L;
180     static final long C2 = C1 * 1000L;
181     static final long C3 = C2 * 1000L;
182     static final long C4 = C3 * 60L;
183     static final long C5 = C4 * 60L;
184     static final long C6 = C5 * 24L;
185 
186     static final long MAX = Long.MAX_VALUE;
187 
188     /**
189      * Scale d by m, checking for overflow.
190      * This has a short name to make above code more readable.
191      */
192     static long x(long d, long m, long over) {
193         if (d >  over) return Long.MAX_VALUE;
194         if (d < -over) return Long.MIN_VALUE;
195         return d * m;
196     }
197 
198     // To maintain full signature compatibility with 1.5, and to improve the
199     // clarity of the generated javadoc (see 6287639: Abstract methods in
200     // enum classes should not be listed as abstract), method convert
201     // etc. are not declared abstract but otherwise act as abstract methods.
202 
203     /**
204      * Converts the given time duration in the given unit to this unit.
205      * Conversions from finer to coarser granularities truncate, so
206      * lose precision. For example, converting {@code 999} milliseconds
207      * to seconds results in {@code 0}. Conversions from coarser to
208      * finer granularities with arguments that would numerically
209      * overflow saturate to {@code Long.MIN_VALUE} if negative or
210      * {@code Long.MAX_VALUE} if positive.
211      *
212      * <p>For example, to convert 10 minutes to milliseconds, use:
213      * {@code TimeUnit.MILLISECONDS.convert(10L, TimeUnit.MINUTES)}
214      *
215      * @param sourceDuration the time duration in the given {@code sourceUnit}
216      * @param sourceUnit the unit of the {@code sourceDuration} argument
217      * @return the converted duration in this unit,
218      * or {@code Long.MIN_VALUE} if conversion would negatively
219      * overflow, or {@code Long.MAX_VALUE} if it would positively overflow.
220      */
221     public long convert(long sourceDuration, TimeUnit sourceUnit) {
222         throw new AbstractMethodError();
223     }
224 
225     /**
226      * Equivalent to
227      * {@link #convert(long, TimeUnit) NANOSECONDS.convert(duration, this)}.
228      * @param duration the duration
229      * @return the converted duration,
230      * or {@code Long.MIN_VALUE} if conversion would negatively
231      * overflow, or {@code Long.MAX_VALUE} if it would positively overflow.
232      */
233     public long toNanos(long duration) {
234         throw new AbstractMethodError();
235     }
236 
237     /**
238      * Equivalent to
239      * {@link #convert(long, TimeUnit) MICROSECONDS.convert(duration, this)}.
240      * @param duration the duration
241      * @return the converted duration,
242      * or {@code Long.MIN_VALUE} if conversion would negatively
243      * overflow, or {@code Long.MAX_VALUE} if it would positively overflow.
244      */
245     public long toMicros(long duration) {
246         throw new AbstractMethodError();
247     }
248 
249     /**
250      * Equivalent to
251      * {@link #convert(long, TimeUnit) MILLISECONDS.convert(duration, this)}.
252      * @param duration the duration
253      * @return the converted duration,
254      * or {@code Long.MIN_VALUE} if conversion would negatively
255      * overflow, or {@code Long.MAX_VALUE} if it would positively overflow.
256      */
257     public long toMillis(long duration) {
258         throw new AbstractMethodError();
259     }
260 
261     /**
262      * Equivalent to
263      * {@link #convert(long, TimeUnit) SECONDS.convert(duration, this)}.
264      * @param duration the duration
265      * @return the converted duration,
266      * or {@code Long.MIN_VALUE} if conversion would negatively
267      * overflow, or {@code Long.MAX_VALUE} if it would positively overflow.
268      */
269     public long toSeconds(long duration) {
270         throw new AbstractMethodError();
271     }
272 
273     /**
274      * Equivalent to
275      * {@link #convert(long, TimeUnit) MINUTES.convert(duration, this)}.
276      * @param duration the duration
277      * @return the converted duration,
278      * or {@code Long.MIN_VALUE} if conversion would negatively
279      * overflow, or {@code Long.MAX_VALUE} if it would positively overflow.
280      * @since 1.6
281      */
282     public long toMinutes(long duration) {
283         throw new AbstractMethodError();
284     }
285 
286     /**
287      * Equivalent to
288      * {@link #convert(long, TimeUnit) HOURS.convert(duration, this)}.
289      * @param duration the duration
290      * @return the converted duration,
291      * or {@code Long.MIN_VALUE} if conversion would negatively
292      * overflow, or {@code Long.MAX_VALUE} if it would positively overflow.
293      * @since 1.6
294      */
295     public long toHours(long duration) {
296         throw new AbstractMethodError();
297     }
298 
299     /**
300      * Equivalent to
301      * {@link #convert(long, TimeUnit) DAYS.convert(duration, this)}.
302      * @param duration the duration
303      * @return the converted duration
304      * @since 1.6
305      */
306     public long toDays(long duration) {
307         throw new AbstractMethodError();
308     }
309 
310     /**
311      * Utility to compute the excess-nanosecond argument to wait,
312      * sleep, join.
313      * @param d the duration
314      * @param m the number of milliseconds
315      * @return the number of nanoseconds
316      */
317     abstract int excessNanos(long d, long m);
318 
319     /**
320      * Performs a timed {@link Object#wait(long, int) Object.wait}
321      * using this time unit.
322      * This is a convenience method that converts timeout arguments
323      * into the form required by the {@code Object.wait} method.
324      *
325      * <p>For example, you could implement a blocking {@code poll}
326      * method (see {@link BlockingQueue#poll BlockingQueue.poll})
327      * using:
328      *
329      *  <pre> {@code
330      * public synchronized Object poll(long timeout, TimeUnit unit)
331      *     throws InterruptedException {
332      *   while (empty) {
333      *     unit.timedWait(this, timeout);
334      *     ...
335      *   }
336      * }}</pre>
337      *
338      * @param obj the object to wait on
339      * @param timeout the maximum time to wait. If less than
340      * or equal to zero, do not wait at all.
341      * @throws InterruptedException if interrupted while waiting
342      */
343     public void timedWait(Object obj, long timeout)
344             throws InterruptedException {
345         if (timeout > 0) {
346             long ms = toMillis(timeout);
347             int ns = excessNanos(timeout, ms);
348             obj.wait(ms, ns);
349         }
350     }
351 
352     /**
353      * Performs a timed {@link Thread#join(long, int) Thread.join}
354      * using this time unit.
355      * This is a convenience method that converts time arguments into the
356      * form required by the {@code Thread.join} method.
357      *
358      * @param thread the thread to wait for
359      * @param timeout the maximum time to wait. If less than
360      * or equal to zero, do not wait at all.
361      * @throws InterruptedException if interrupted while waiting
362      */
363     public void timedJoin(Thread thread, long timeout)
364             throws InterruptedException {
365         if (timeout > 0) {
366             long ms = toMillis(timeout);
367             int ns = excessNanos(timeout, ms);
368             thread.join(ms, ns);
369         }
370     }
371 
372     /**
373      * Performs a {@link Thread#sleep(long, int) Thread.sleep} using
374      * this time unit.
375      * This is a convenience method that converts time arguments into the
376      * form required by the {@code Thread.sleep} method.
377      *
378      * @param timeout the minimum time to sleep. If less than
379      * or equal to zero, do not sleep at all.
380      * @throws InterruptedException if interrupted while sleeping
381      */
382     public void sleep(long timeout) throws InterruptedException {
383         if (timeout > 0) {
384             long ms = toMillis(timeout);
385             int ns = excessNanos(timeout, ms);
386             Thread.sleep(ms, ns);
387         }
388     }
389 
390 }
View Code

本文为个人原创作品

原文地址:https://www.cnblogs.com/wusiwee/p/10418379.html