赞
踩
本文来源于我的另一篇博客,由于另一篇博客不再更新,遂 全部转入CSDN
注:redis服务器要先开启! 或者连接远程服务器上的 Redis,但是依然要开启服务,不然会一直 TimeOut! 欢迎关注公众哦,每日推文
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
# 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; /** * 存入缓存键 key:value * first :siwei * second:siweiWu (30秒过期时间) */ @Test public void setRedis() { //缓存中最常用的方法 redisTemplate.opsForValue().set("first","siwei"); //设置缓存过期时间为30 单位:秒 //关于TimeUnit下面有部分源码截图 redisTemplate.opsForValue().set("second","siweiWu",30, TimeUnit.SECONDS); System.out.println("存入缓存成功"); } /** * 根据key 获取 value */ @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); } /** * 根据key 删除缓存 */ @Test public void delRedis() { //根据key删除缓存 Boolean first = redisTemplate.delete("first"); System.out.println("是否删除成功:"+first); }
贴上公司日常项目开发中使用的缓存服务层代码(可直接拷贝使用,我把包也贴出来,自行导包奥~
请原谅我不会折叠代码,MarkDown语法的小菜鸡一枚~)
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); }
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; } }
注:其他 Service 层使用时,只需要将 RedisService 注入即可像普通Service层一样调用
StringRedisTemplate相关方法我也总结了一下,可能不是很全 不过还是够用了
上面设置缓存过期时间的TimeUnit源码 部分截图说明(后面会附上全部的源码——总390行,):
全部源码:
/* * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * Written by Doug Lea with assistance from members of JCP JSR-166 * Expert Group and released to the public domain, as explained at * http://creativecommons.org/publicdomain/zero/1.0/ */ package java.util.concurrent; /** * A {@code TimeUnit} represents time durations at a given unit of * granularity and provides utility methods to convert across units, * and to perform timing and delay operations in these units. A * {@code TimeUnit} does not maintain time information, but only * helps organize and use time representations that may be maintained * separately across various contexts. A nanosecond is defined as one * thousandth of a microsecond, a microsecond as one thousandth of a * millisecond, a millisecond as one thousandth of a second, a minute * as sixty seconds, an hour as sixty minutes, and a day as twenty four * hours. * * <p>A {@code TimeUnit} is mainly used to inform time-based methods * how a given timing parameter should be interpreted. For example, * the following code will timeout in 50 milliseconds if the {@link * java.util.concurrent.locks.Lock lock} is not available: * * <pre> {@code * Lock lock = ...; * if (lock.tryLock(50L, TimeUnit.MILLISECONDS)) ...}</pre> * * while this code will timeout in 50 seconds: * <pre> {@code * Lock lock = ...; * if (lock.tryLock(50L, TimeUnit.SECONDS)) ...}</pre> * * Note however, that there is no guarantee that a particular timeout * implementation will be able to notice the passage of time at the * same granularity as the given {@code TimeUnit}. * * @since 1.5 * @author Doug Lea */ public enum TimeUnit { /** * Time unit representing one thousandth of a microsecond */ NANOSECONDS { public long toNanos(long d) { return d; } public long toMicros(long d) { return d/(C1/C0); } public long toMillis(long d) { return d/(C2/C0); } public long toSeconds(long d) { return d/(C3/C0); } public long toMinutes(long d) { return d/(C4/C0); } public long toHours(long d) { return d/(C5/C0); } public long toDays(long d) { return d/(C6/C0); } public long convert(long d, TimeUnit u) { return u.toNanos(d); } int excessNanos(long d, long m) { return (int)(d - (m*C2)); } }, /** * Time unit representing one thousandth of a millisecond */ MICROSECONDS { public long toNanos(long d) { return x(d, C1/C0, MAX/(C1/C0)); } public long toMicros(long d) { return d; } public long toMillis(long d) { return d/(C2/C1); } public long toSeconds(long d) { return d/(C3/C1); } public long toMinutes(long d) { return d/(C4/C1); } public long toHours(long d) { return d/(C5/C1); } public long toDays(long d) { return d/(C6/C1); } public long convert(long d, TimeUnit u) { return u.toMicros(d); } int excessNanos(long d, long m) { return (int)((d*C1) - (m*C2)); } }, /** * Time unit representing one thousandth of a second */ MILLISECONDS { public long toNanos(long d) { return x(d, C2/C0, MAX/(C2/C0)); } public long toMicros(long d) { return x(d, C2/C1, MAX/(C2/C1)); } public long toMillis(long d) { return d; } public long toSeconds(long d) { return d/(C3/C2); } public long toMinutes(long d) { return d/(C4/C2); } public long toHours(long d) { return d/(C5/C2); } public long toDays(long d) { return d/(C6/C2); } public long convert(long d, TimeUnit u) { return u.toMillis(d); } int excessNanos(long d, long m) { return 0; } }, /** * Time unit representing one second */ SECONDS { public long toNanos(long d) { return x(d, C3/C0, MAX/(C3/C0)); } public long toMicros(long d) { return x(d, C3/C1, MAX/(C3/C1)); } public long toMillis(long d) { return x(d, C3/C2, MAX/(C3/C2)); } public long toSeconds(long d) { return d; } public long toMinutes(long d) { return d/(C4/C3); } public long toHours(long d) { return d/(C5/C3); } public long toDays(long d) { return d/(C6/C3); } public long convert(long d, TimeUnit u) { return u.toSeconds(d); } int excessNanos(long d, long m) { return 0; } }, /** * Time unit representing sixty seconds */ MINUTES { public long toNanos(long d) { return x(d, C4/C0, MAX/(C4/C0)); } public long toMicros(long d) { return x(d, C4/C1, MAX/(C4/C1)); } public long toMillis(long d) { return x(d, C4/C2, MAX/(C4/C2)); } public long toSeconds(long d) { return x(d, C4/C3, MAX/(C4/C3)); } public long toMinutes(long d) { return d; } public long toHours(long d) { return d/(C5/C4); } public long toDays(long d) { return d/(C6/C4); } public long convert(long d, TimeUnit u) { return u.toMinutes(d); } int excessNanos(long d, long m) { return 0; } }, /** * Time unit representing sixty minutes */ HOURS { public long toNanos(long d) { return x(d, C5/C0, MAX/(C5/C0)); } public long toMicros(long d) { return x(d, C5/C1, MAX/(C5/C1)); } public long toMillis(long d) { return x(d, C5/C2, MAX/(C5/C2)); } public long toSeconds(long d) { return x(d, C5/C3, MAX/(C5/C3)); } public long toMinutes(long d) { return x(d, C5/C4, MAX/(C5/C4)); } public long toHours(long d) { return d; } public long toDays(long d) { return d/(C6/C5); } public long convert(long d, TimeUnit u) { return u.toHours(d); } int excessNanos(long d, long m) { return 0; } }, /** * Time unit representing twenty four hours */ DAYS { public long toNanos(long d) { return x(d, C6/C0, MAX/(C6/C0)); } public long toMicros(long d) { return x(d, C6/C1, MAX/(C6/C1)); } public long toMillis(long d) { return x(d, C6/C2, MAX/(C6/C2)); } public long toSeconds(long d) { return x(d, C6/C3, MAX/(C6/C3)); } public long toMinutes(long d) { return x(d, C6/C4, MAX/(C6/C4)); } public long toHours(long d) { return x(d, C6/C5, MAX/(C6/C5)); } public long toDays(long d) { return d; } public long convert(long d, TimeUnit u) { return u.toDays(d); } int excessNanos(long d, long m) { return 0; } }; // Handy constants for conversion methods static final long C0 = 1L; static final long C1 = C0 * 1000L; static final long C2 = C1 * 1000L; static final long C3 = C2 * 1000L; static final long C4 = C3 * 60L; static final long C5 = C4 * 60L; static final long C6 = C5 * 24L; static final long MAX = Long.MAX_VALUE; /** * Scale d by m, checking for overflow. * This has a short name to make above code more readable. */ static long x(long d, long m, long over) { if (d > over) return Long.MAX_VALUE; if (d < -over) return Long.MIN_VALUE; return d * m; } // To maintain full signature compatibility with 1.5, and to improve the // clarity of the generated javadoc (see 6287639: Abstract methods in // enum classes should not be listed as abstract), method convert // etc. are not declared abstract but otherwise act as abstract methods. /** * Converts the given time duration in the given unit to this unit. * Conversions from finer to coarser granularities truncate, so * lose precision. For example, converting {@code 999} milliseconds * to seconds results in {@code 0}. Conversions from coarser to * finer granularities with arguments that would numerically * overflow saturate to {@code Long.MIN_VALUE} if negative or * {@code Long.MAX_VALUE} if positive. * * <p>For example, to convert 10 minutes to milliseconds, use: * {@code TimeUnit.MILLISECONDS.convert(10L, TimeUnit.MINUTES)} * * @param sourceDuration the time duration in the given {@code sourceUnit} * @param sourceUnit the unit of the {@code sourceDuration} argument * @return the converted duration in this unit, * or {@code Long.MIN_VALUE} if conversion would negatively * overflow, or {@code Long.MAX_VALUE} if it would positively overflow. */ public long convert(long sourceDuration, TimeUnit sourceUnit) { throw new AbstractMethodError(); } /** * Equivalent to * {@link #convert(long, TimeUnit) NANOSECONDS.convert(duration, this)}. * @param duration the duration * @return the converted duration, * or {@code Long.MIN_VALUE} if conversion would negatively * overflow, or {@code Long.MAX_VALUE} if it would positively overflow. */ public long toNanos(long duration) { throw new AbstractMethodError(); } /** * Equivalent to * {@link #convert(long, TimeUnit) MICROSECONDS.convert(duration, this)}. * @param duration the duration * @return the converted duration, * or {@code Long.MIN_VALUE} if conversion would negatively * overflow, or {@code Long.MAX_VALUE} if it would positively overflow. */ public long toMicros(long duration) { throw new AbstractMethodError(); } /** * Equivalent to * {@link #convert(long, TimeUnit) MILLISECONDS.convert(duration, this)}. * @param duration the duration * @return the converted duration, * or {@code Long.MIN_VALUE} if conversion would negatively * overflow, or {@code Long.MAX_VALUE} if it would positively overflow. */ public long toMillis(long duration) { throw new AbstractMethodError(); } /** * Equivalent to * {@link #convert(long, TimeUnit) SECONDS.convert(duration, this)}. * @param duration the duration * @return the converted duration, * or {@code Long.MIN_VALUE} if conversion would negatively * overflow, or {@code Long.MAX_VALUE} if it would positively overflow. */ public long toSeconds(long duration) { throw new AbstractMethodError(); } /** * Equivalent to * {@link #convert(long, TimeUnit) MINUTES.convert(duration, this)}. * @param duration the duration * @return the converted duration, * or {@code Long.MIN_VALUE} if conversion would negatively * overflow, or {@code Long.MAX_VALUE} if it would positively overflow. * @since 1.6 */ public long toMinutes(long duration) { throw new AbstractMethodError(); } /** * Equivalent to * {@link #convert(long, TimeUnit) HOURS.convert(duration, this)}. * @param duration the duration * @return the converted duration, * or {@code Long.MIN_VALUE} if conversion would negatively * overflow, or {@code Long.MAX_VALUE} if it would positively overflow. * @since 1.6 */ public long toHours(long duration) { throw new AbstractMethodError(); } /** * Equivalent to * {@link #convert(long, TimeUnit) DAYS.convert(duration, this)}. * @param duration the duration * @return the converted duration * @since 1.6 */ public long toDays(long duration) { throw new AbstractMethodError(); } /** * Utility to compute the excess-nanosecond argument to wait, * sleep, join. * @param d the duration * @param m the number of milliseconds * @return the number of nanoseconds */ abstract int excessNanos(long d, long m); /** * Performs a timed {@link Object#wait(long, int) Object.wait} * using this time unit. * This is a convenience method that converts timeout arguments * into the form required by the {@code Object.wait} method. * * <p>For example, you could implement a blocking {@code poll} * method (see {@link BlockingQueue#poll BlockingQueue.poll}) * using: * * <pre> {@code * public synchronized Object poll(long timeout, TimeUnit unit) * throws InterruptedException { * while (empty) { * unit.timedWait(this, timeout); * ... * } * }}</pre> * * @param obj the object to wait on * @param timeout the maximum time to wait. If less than * or equal to zero, do not wait at all. * @throws InterruptedException if interrupted while waiting */ public void timedWait(Object obj, long timeout) throws InterruptedException { if (timeout > 0) { long ms = toMillis(timeout); int ns = excessNanos(timeout, ms); obj.wait(ms, ns); } } /** * Performs a timed {@link Thread#join(long, int) Thread.join} * using this time unit. * This is a convenience method that converts time arguments into the * form required by the {@code Thread.join} method. * * @param thread the thread to wait for * @param timeout the maximum time to wait. If less than * or equal to zero, do not wait at all. * @throws InterruptedException if interrupted while waiting */ public void timedJoin(Thread thread, long timeout) throws InterruptedException { if (timeout > 0) { long ms = toMillis(timeout); int ns = excessNanos(timeout, ms); thread.join(ms, ns); } } /** * Performs a {@link Thread#sleep(long, int) Thread.sleep} using * this time unit. * This is a convenience method that converts time arguments into the * form required by the {@code Thread.sleep} method. * * @param timeout the minimum time to sleep. If less than * or equal to zero, do not sleep at all. * @throws InterruptedException if interrupted while sleeping */ public void sleep(long timeout) throws InterruptedException { if (timeout > 0) { long ms = toMillis(timeout); int ns = excessNanos(timeout, ms); Thread.sleep(ms, ns); } } }
不要害怕学习,知识没有重量,它是你随时可以获取的又随时可以携带的宝库。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。