BingheGuide | 冰河指南
| 《深入理解高并发编程:核心原理与案例实战》
| 《深入理解高并发编程:JDK核心技术》
| 数据同步
| Spring核心技术
| 分布式限流
| 分布式锁
| 分布式缓存
| 异步并行框架
| 分布式事务
| 简易版IM
| 微信SDK
| 延迟队列
| 分布式ID
| 更多搜索...添加微信:hacker_binghe - 备注来意
冰河技术知识星球是冰河创建的付费编程学习、交流社群,我相信每个程序员的硬盘或者云盘里存放着几百GB甚至几TB的编程资料和学习视频,但多又怎么样?出现问题你能问谁?又能去哪里咨询问题呢?冰河的知识星球则不同,在星球里冰河会对你的问题进行 1v1 解答,为你指定学习路线、学习方案和规划职业生涯路线。最终的目标就是有针对性的帮助每一位加入星球的小伙伴,通过学习星球的硬核技术和项目,提升业务理解能力、系统架构能力,充分掌握大厂真正落地的核心技术、架构思维、编程思想、代码技巧,不只是为了面试,更多的是为自己的职业生涯保驾护航。
如果你一直在小公司做CRUD,一直忙碌于外包项目,正在迷茫,找不到除了CRUD以外更具深度的项目,不知道学什么,从哪里学,该怎么学,怎么让自己更具竞争力,怎么更好的提升自己,怎么将自己的能力充分体现在简历上,怎么在面试短短的几十分钟内充分展现自己的水平。冰河技术知识星球会给你答案,冰河会在这里为你铺好路,让你一往直前。
知识星球支持安卓、IOS、PC网页端和小程序,可以随时打开学习,在你每天上下班坐公交和地铁时,或者在带薪如厕时,都可以随时打开知识星球学习,也许某次的学习就能让你在面试、述职、升职加薪、晋升答辩时脱颖而出!
星球APP&小程序截图:
星球PC网页端截图:
各位小伙伴们可以下载知识星球APP,加入冰河技术知识星球体验一下。
加入星球,你可以获得已经在编程这条路上踩坑多年的互联网资深技术专家,为你提供的服务。
很多小伙伴困于自己在小厂、外包或者刚毕业和未毕业,手里根本就没有什么拿的出手的项目,也没有什么好的阅历,导致投向大厂的简历石沉大海。
加入星球可以直接学习到冰河在大厂多年沉淀下来的核心技术,带你编写超出大厂预期的实战项目,包括但不限于:并发编程、性能调优、框架源码、分布式、微服务、领域驱动设计、互联网工程、Seckill分布式秒杀系统、分布式IM系统、分布式高性能RPC框架、高性能网关等。
其实很多技术和知识并不难,而是你不知道,也没有人告诉你,如果你自己去探索、去研究,可能要花费数月甚至数年才能搞懂。而这样的技术、知识和项目在冰河的知识星球,每天都在产出。你可以在星球向冰河提问题项目架构设计、面试面经问题、晋升答辩细节,也可以参见冰河回答其他小伙伴的疑问,这些内容都能够帮你少走弯路,在最短的时间内提升自己的综合素质和硬核技能。
注:限于篇幅,上图只接触了少部分回答,大部分回答内容和学习建议没截出来,大家可自行到星球查看。
这只是星球其中一个问题的回答,有时,小伙伴一句话的提问,可能要写几百上千字来回答,在星球提问基本就赚了!
冰河会在星球中回答大量这样的问题,有时小伙伴备注私聊的问题,我会选择单独发给小伙伴们,在星球的每一个菜单栏下,都对应着相关的知识内容、专栏文档、技术小册、视频课程、技术资料等等,坚决不割韭菜,让每一个加入星球的小伙伴都感觉值得。
冰河在星球除了帮助小伙伴们优化、改进简历外,还为大家提供了1000+套星球专属精美简历模板与面试技巧。
部分简历模板如下所示。
部分面试技巧如下所示。
星球价格 ¥299 一年,新用户领券(关注冰河技术公众号,回复星球领券。或者点击 加入星球 扫码加入)加入,老用户续费5折一年(星球会不断开发新的技术专栏、硬核项目、技术小册等内容)。
加入星球后,如果不满意,3天内可以全额退款,感兴趣的小伙伴可以先加入体验,判断对自己是否有价值。
注意: 加入星球后,阅读星球置顶消息
https://t.zsxq.com/14EatpDHH 申请项目代码权限。
同时,按照《中华人民共和国著作权法实施条例》未经原作者允许和书面授权,禁止以任何理由和目的,分享星球项目到其他任何github、gitee等平台,违反可追究进一步的法律行动。
星球值不值得学,来看看加入星球的小伙伴怎么说吧。
跟着冰河学,你只管努力提升自己的技能和水平,有问题及时向冰河提问,进大厂是迟早的事儿。
1.星球内的专栏和硬核实战项目都是冰河本人原创,加入星球可以学习星球内的所有技术和项目,每个项目的实际价值都远超门票,会带着大家从零开始架构设计,手写硬核项目,搭配有专栏文档,笔记、源码工程,遇到问题可以提,碰到Bug可以修复,这肯定比单独买一个课程或者一套源码要划算的多。星球门票其实远不及培训班、补习班一节课的钱,并且他们的课程可能还没有冰河讲的透彻,让你听的明白。
2.冰河每天会投入大量精力在星球的创作上,包括分享技术、架构设计、项目开发、答疑解惑、优化简历、就业与晋升指导等。这些内容会占据冰河大量的时间和精力,需要每天晚上9点~12点,周末和假期不断维护。所以,冰河的星球会随着项目的递增和加入的人数涨价(本次涨价¥20),否则,真的有点维护不过来了。也真心希望加入星球的小伙伴给自己一个交代,下定决心,一起进步。
3.如果在星球的努力真的让你实现了跳槽大厂、升职加薪的目标,再回过头来看,你会觉得这是一笔对自己最有价值的投资。
4.最后,星球会随着项目的递增和加入的人数涨价,感谢大家的理解!但是,已经加入星球的小伙伴,每次续费的折扣都是很大的,只相当于付了星球新增技术、专栏和项目的费用。对比下来,这个价格就相当便宜了。
冰河的知识星球是一个简单、干净、纯粹交流技术的星球,不吹水,目前领券加入享5折优惠,价值远超门票。加入星球的用户,记得添加冰河微信:hacker_binghe,冰河拉你进星球专属VIP交流群。
📚 基于Redis解决缓存击穿、穿透和雪崩问题的通用解决方案,拿来即用。支持存储对象、集合、简单数据类型等。无需提前将数据存入Redis,直接使用提供的分布式缓存接口查询数据即可,附带完善的单元测试用例,方便学习使用。
分布式缓存核心接口源码详见:io.binghe.redis.cache.distribute.DistributeCacheService
默认基于Redis的实现类的源码详见:io.binghe.redis.cache.distribute.redis.RedisDistributeCacheService
也可以基于SpringBoot的@ConditionalOnProperty
注解扩展基于其他缓存中间件的实现类
项目配有完善的单元测试用例,具体测试源码详见:src/test/java
目录下的io.binghe.redis.test.DistributeCacheServiceTest
分布式缓存核心接口源码详见:io.binghe.redis.cache.distribute.DistributeCacheService
/**
* @author binghe(微信 : hacker_binghe)
* @version 1.0.0
* @description 分布式缓存接口,通用型接口,在满足分布式缓存的需求时,解决了缓存击穿、穿透和雪崩的问题
* @github https://github.com/binghe001
* @copyright 公众号: 冰河技术
*/
public interface DistributeCacheService {
/**
* 永久缓存
* @param key 缓存key
* @param value 缓存value
*/
void set(String key, Object value);
/**
* 将数据缓存一段时间
* @param key 缓存key
* @param value 缓存value
* @param timeout 物理缓存的时长
* @param unit 物理时间单位
*/
void set(String key, Object value, Long timeout, TimeUnit unit);
/**
* 保存缓存时设置逻辑过期时间
* @param key 缓存key
* @param value 缓存value
* @param timeout 缓存逻辑过期时长
* @param unit 缓存逻辑时间单位
*/
void setWithLogicalExpire(String key, Object value, Long timeout, TimeUnit unit);
/**
* 获取缓存中的数据
* @param key 缓存key
* @return 缓存value
*/
String get(String key);
/**
* 带参数查询对象和简单类型数据,防止缓存穿透
* @param keyPrefix 缓存key的前缀
* @param id 缓存的业务标识,
* @param type 缓存的实际对象类型
* @param dbFallback 查询数据库的Function函数
* @param timeout 缓存的时长
* @param unit 时间单位
* @return 返回业务数据
* @param <R> 结果泛型
* @param <ID> 查询数据库参数泛型,也是参数泛型类型
*/
<R,ID> R queryWithPassThrough(String keyPrefix, ID id, Class<R> type, Function<ID, R> dbFallback, Long timeout, TimeUnit unit);
/**
* 不带参数查询对象和简单类型数据,防止缓存穿透
* @param keyPrefix key的前缀
* @param type 缓存的实际对象类型
* @param dbFallback 无参数查询数据库数据
* @param timeout 缓存的时长
* @param unit 时间单位
* @return 返回业务数据
* @param <R> 结果泛型
*/
<R> R queryWithPassThroughWithoutArgs(String keyPrefix, Class<R> type, Supplier<R> dbFallback, Long timeout, TimeUnit unit);
/**
* 带参数查询集合数据,防止缓存穿透
* @param keyPrefix 缓存key的前缀
* @param id 缓存的业务标识,
* @param type 缓存的实际对象类型
* @param dbFallback 查询数据库的Function函数
* @param timeout 缓存的时长
* @param unit 时间单位
* @return 返回业务数据
* @param <R> 结果泛型
* @param <ID> 查询数据库参数泛型,也是参数泛型类型
*/
<R,ID> List<R> queryWithPassThroughList(String keyPrefix, ID id, Class<R> type, Function<ID, List<R>> dbFallback, Long timeout, TimeUnit unit);
/**
* 不带参数查询集合数据,防止缓存穿透
* @param keyPrefix 缓存key的前缀
* @param type 缓存的实际对象类型
* @param dbFallback 无参数查询数据库数据
* @param timeout 缓存的时长
* @param unit 时间单位
* @return 返回业务数据
* @param <R> 结果泛型
*/
<R> List<R> queryWithPassThroughListWithoutArgs(String keyPrefix, Class<R> type, Supplier<List<R>> dbFallback, Long timeout, TimeUnit unit);
/**
* 带参数查询数据,按照逻辑过期时间读取缓存数据,新开线程重建缓存,其他线程直接返回逻辑过期数据,不占用资源
* @param keyPrefix 缓存key的前缀
* @param id 缓存业务标识,也是查询数据库的参数
* @param type 缓存的实际对象类型
* @param dbFallback 查询数据库的Function函数
* @param timeout 缓存逻辑过期时长
* @param unit 缓存逻辑过期时间单位
* @return 业务数据
* @param <R> 结果数据泛型类型
* @param <ID> 查询数据库泛型类型,也是参数泛型类型
*/
<R, ID> R queryWithLogicalExpire(String keyPrefix, ID id, Class<R> type, Function<ID, R> dbFallback, Long timeout, TimeUnit unit);
/**
* 不带参数查询数据,按照逻辑过期时间读取缓存数据,新开线程重建缓存,其他线程直接返回逻辑过期数据,不占用资源
* @param keyPrefix 缓存key的前缀
* @param type 缓存的实际对象类型
* @param dbFallback 无参数查询数据库数据
* @param timeout 缓存的时长
* @param unit 时间单位
* @return 返回业务数据
* @param <R> 结果泛型
*/
<R> R queryWithLogicalExpireWithoutArgs(String keyPrefix, Class<R> type, Supplier<R> dbFallback, Long timeout, TimeUnit unit);
/**
* 带参数查询集合数据,按照逻辑过期时间读取缓存数据,新开线程重建缓存,其他线程直接返回逻辑过期数据,不占用资源
* @param keyPrefix 缓存key的前缀
* @param id 缓存业务标识,也是查询数据库的参数
* @param type 缓存的实际对象类型
* @param dbFallback 查询数据库的Function函数
* @param timeout 缓存逻辑过期时长
* @param unit 缓存逻辑过期时间单位
* @return 业务数据
* @param <R> 结果数据泛型类型
* @param <ID> 查询数据库泛型类型,也是参数泛型类型
*/
<R, ID> List<R> queryWithLogicalExpireList(String keyPrefix, ID id, Class<R> type, Function<ID, List<R>> dbFallback, Long timeout, TimeUnit unit);
/**
* 不带参数查询集合数据,按照逻辑过期时间读取缓存数据,新开线程重建缓存,其他线程直接返回逻辑过期数据,不占用资源
* @param keyPrefix 缓存key的前缀
* @param type 缓存的实际对象类型
* @param dbFallback 无参数查询数据库数据
* @param timeout 缓存的时长
* @param unit 时间单位
* @return 返回业务数据
* @param <R> 结果泛型
*/
<R> List<R> queryWithLogicalExpireListWithoutArgs(String keyPrefix, Class<R> type, Supplier<List<R>> dbFallback, Long timeout, TimeUnit unit);
/**
* 带参数查询数据,按照互斥锁方式获取缓存数据,同一时刻只有一个线程访问数据库,其他线程访问不到数据重试
* @param keyPrefix 缓存key的前缀
* @param id 缓存业务标识,也是查询数据库的参数
* @param type 缓存的实际对象类型
* @param dbFallback 查询数据库的Function函数
* @param timeout 缓存时长
* @param unit 时间单位
* @return 业务数据
* @param <R> 结果数据泛型类型
* @param <ID> 查询数据库泛型类型,也是参数泛型类型
*/
<R, ID> R queryWithMutex(String keyPrefix, ID id, Class<R> type, Function<ID, R> dbFallback, Long timeout, TimeUnit unit);
/**
* 不带参数查询数据,按照互斥锁方式获取缓存数据,同一时刻只有一个线程访问数据库,其他线程访问不到数据重试
* @param keyPrefix 缓存key的前缀
* @param type 缓存的实际对象类型
* @param dbFallback 无参数查询数据库数据
* @param timeout 缓存时长
* @param unit 时间单位
* @return 返回业务数据
* @param <R> 结果泛型
*/
<R> R queryWithMutexWithoutArgs(String keyPrefix, Class<R> type, Supplier<R> dbFallback, Long timeout, TimeUnit unit);
/**
* 带参数查询数据,按照互斥锁方式获取缓存数据,同一时刻只有一个线程访问数据库,其他线程访问不到数据重试
* @param keyPrefix 缓存key的前缀
* @param id 缓存业务标识,也是查询数据库的参数
* @param type 缓存的实际对象类型
* @param dbFallback 查询数据库的Function函数
* @param timeout 缓存时长
* @param unit 时间单位
* @return 业务数据
* @param <R> 结果数据泛型类型
* @param <ID> 查询数据库泛型类型,也是参数泛型类型
*/
<R, ID> List<R> queryWithMutexList(String keyPrefix, ID id, Class<R> type, Function<ID, List<R>> dbFallback, Long timeout, TimeUnit unit);
/**
* 不带参数查询数据,按照互斥锁方式获取缓存数据,同一时刻只有一个线程访问数据库,其他线程访问不到数据重试
* @param keyPrefix 缓存key的前缀
* @param type 缓存的实际对象类型
* @param dbFallback 无参数查询数据库数据
* @param timeout 缓存时长
* @param unit 时间单位
* @return 返回业务数据
* @param <R> 结果泛型
*/
<R> List<R> queryWithMutexListWithoutArgs(String keyPrefix, Class<R> type, Supplier<List<R>> dbFallback, Long timeout, TimeUnit unit);
/**
* 将对象类型的json字符串转换成泛型类型
* @param obj 未知类型对象
* @param type 泛型Class类型
* @return 泛型对象
* @param <R> 泛型
*/
default <R> R getResult(Object obj, Class<R> type){
if (obj == null){
return null;
}
//简单类型
if (TypeConversion.isSimpleType(obj)){
return Convert.convert(type, obj);
}
return JSONUtil.toBean(JSONUtil.toJsonStr(obj), type);
}
/**
* 将对象类型的json字符串转换成泛型类型的List集合
* @param str json字符串
* @param type 泛型Class类型
* @return 泛型List集合
* @param <R> 泛型
*/
default <R> List<R> getResultList(String str, Class<R> type){
if (StrUtil.isEmpty(str)){
return null;
}
return JSONUtil.toList(JSONUtil.parseArray(str), type);
}
/**
* 获取简单的key
* @param key key
* @return 返回key
*/
default String getKey(String key){
return getKey(key, null);
}
/**
* 不确定参数类型的情况下,使用MD5计算参数的拼接到Redis中的唯一Key
* @param keyPrefix 缓存key的前缀
* @param id 泛型参数
* @return 拼接好的缓存key
* @param <ID> 参数泛型类型
*/
default <ID> String getKey(String keyPrefix, ID id){
if (id == null){
return keyPrefix;
}
String key = "";
//简单数据类型与简单字符串
if (TypeConversion.isSimpleType(id)){
key = StrUtil.toString(id);
}else {
key = MD5.create().digestHex(JSONUtil.toJsonStr(id));
}
if (StrUtil.isEmpty(key)){
key = "";
}
return keyPrefix.concat(key);
}
/**
* 获取要保存到缓存中的value字符串,可能是简单类型,也可能是对象类型,也可能是集合数组等
* @param value 要保存的value值
* @return 处理好的字符串
*/
default String getValue(Object value){
return TypeConversion.isSimpleType(value) ? String.valueOf(value) : JSONUtil.toJsonStr(value);
}
}
1.User类模拟从数据库查询对象类型的数据
源码详见:io.binghe.redis.test.bean.User
public class User {
private Long id;
private String name;
public User() {
}
public User(Long id, String name) {
this.id = id;
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return JSONUtil.toJsonStr(this);
}
}
2.DistributeCacheServiceTest类测试各种场景
源码详见:io.binghe.redis.test.DistributeCacheServiceTest
@SpringBootTest
@RunWith(SpringRunner.class)
public class DistributeCacheServiceTest {
@Autowired
private DistributeCacheService distributeCacheService;
@Test
public void testQueryWithPassThrough(){
User user = distributeCacheService.queryWithPassThrough("pass:through:", 1002852L, User.class, this::getUser, 60L, TimeUnit.SECONDS);
System.out.println(JSONUtil.toJsonStr(user));
}
@Test
public void testQueryWithPassThroughWithoutArgs(){
User user = distributeCacheService.queryWithPassThroughWithoutArgs("pass:through001:", User.class, this::getUserWithoutArgs, 60L, TimeUnit.SECONDS);
System.out.println(JSONUtil.toJsonStr(user));
}
@Test
public void testQuerySimpleDataWithPassThrough(){
Integer id = distributeCacheService.queryWithPassThrough("pass:through2:", 100285210, Integer.class, this::getId, 60L, TimeUnit.SECONDS);
System.out.println(id);
}
@Test
public void testQuerySimpleDataWithPassThroughWithoutArgs(){
Integer id = distributeCacheService.queryWithPassThroughWithoutArgs("pass:through2002:", Integer.class, this::getIdWithoutArgs, 60L, TimeUnit.SECONDS);
System.out.println(id);
}
@Test
public void testQueryWithPassThroughList(){
List<User> list = distributeCacheService.queryWithPassThroughList("pass:through:list:", null, User.class, this::getUserList, 60L, TimeUnit.SECONDS);
System.out.println(JSONUtil.toJsonStr(list));
}
@Test
public void testQueryWithPassThroughListWithoutArgs(){
List<User> list = distributeCacheService.queryWithPassThroughListWithoutArgs("pass:through:list003:", User.class, this::getUserListWithoutArgs, 60L, TimeUnit.SECONDS);
System.out.println(JSONUtil.toJsonStr(list));
}
@Test
public void testQuerySimpleDataWithPassThroughList(){
List<Integer> list = distributeCacheService.queryWithPassThroughList("pass:through:list2:", 100285211, Integer.class, this::getIds, 60L, TimeUnit.SECONDS);
System.out.println(JSONUtil.toJsonStr(list));
}
@Test
public void testQuerySimpleDataWithPassThroughListWithoutArgs(){
List<Integer> list = distributeCacheService.queryWithPassThroughListWithoutArgs("pass:through:list2004:", Integer.class, this::getIdsWithoutArgs, 60L, TimeUnit.SECONDS);
System.out.println(JSONUtil.toJsonStr(list));
}
@Test
public void testQueryWithLogicalExpire(){
User user = distributeCacheService.queryWithLogicalExpire("logical:expire:", 1002852L, User.class, this::getUser, 60L, TimeUnit.SECONDS);
System.out.println(JSONUtil.toJsonStr(user));
}
@Test
public void testQueryWithLogicalExpireWithoutArgs(){
User user = distributeCacheService.queryWithLogicalExpireWithoutArgs("logical:expire005:", User.class, this::getUserWithoutArgs, 60L, TimeUnit.SECONDS);
System.out.println(JSONUtil.toJsonStr(user));
}
@Test
public void testQuerySimpleDataWithLogicalExpire(){
Integer id = distributeCacheService.queryWithLogicalExpire("logical:expire2:", 100285212, Integer.class, this::getId, 60L, TimeUnit.SECONDS);
System.out.println(id);
}
@Test
public void testQuerySimpleDataWithLogicalExpireWithoutArgs(){
Integer id = distributeCacheService.queryWithLogicalExpireWithoutArgs("logical:expire2006:", Integer.class, this::getIdWithoutArgs, 60L, TimeUnit.SECONDS);
System.out.println(id);
}
@Test
public void testQueryWithLogicalExpireList(){
List<User> list = distributeCacheService.queryWithLogicalExpireList("logical:expire:list:", null, User.class, this::getUserList, 60L, TimeUnit.SECONDS);
System.out.println(JSONUtil.toJsonStr(list));
}
@Test
public void testQueryWithLogicalExpireListWithoutArgs(){
List<User> list = distributeCacheService.queryWithLogicalExpireListWithoutArgs("logical:expire:list007:", User.class, this::getUserListWithoutArgs, 60L, TimeUnit.SECONDS);
System.out.println(JSONUtil.toJsonStr(list));
}
@Test
public void testQuerySimpleDataWithLogicalExpireList(){
List<Integer> list = distributeCacheService.queryWithLogicalExpireList("logical:expire:list2:", 100285213, Integer.class, this::getIds, 60L, TimeUnit.SECONDS);
System.out.println(JSONUtil.toJsonStr(list));
}
@Test
public void testQuerySimpleDataWithLogicalExpireListWithoutArgs(){
List<Integer> list = distributeCacheService.queryWithLogicalExpireListWithoutArgs("logical:expire:list2008:", Integer.class, this::getIdsWithoutArgs, 60L, TimeUnit.SECONDS);
System.out.println(JSONUtil.toJsonStr(list));
}
@Test
public void testQueryWithMutex(){
User user = distributeCacheService.queryWithMutex("mutex:", 1002852L, User.class, this::getUser, 60L, TimeUnit.SECONDS);
System.out.println(JSONUtil.toJsonStr(user));
}
@Test
public void testQueryWithMutexWithoutArgs(){
User user = distributeCacheService.queryWithMutexWithoutArgs("mutex009:", User.class, this::getUserWithoutArgs, 60L, TimeUnit.SECONDS);
System.out.println(JSONUtil.toJsonStr(user));
}
@Test
public void testQuerySimpleDataWithMutex(){
Integer id = distributeCacheService.queryWithMutex("mutex2:", 100285214, Integer.class, this::getId, 60L, TimeUnit.SECONDS);
System.out.println(id);
}
@Test
public void testQuerySimpleDataWithMutexWithoutArgs(){
Integer id = distributeCacheService.queryWithMutexWithoutArgs("mutex2010:", Integer.class, this::getIdWithoutArgs, 60L, TimeUnit.SECONDS);
System.out.println(id);
}
@Test
public void testQueryWithMutexList(){
List<User> list = distributeCacheService.queryWithMutexList("mutex:list:", null, User.class, this::getUserList, 60L, TimeUnit.SECONDS);
System.out.println(JSONUtil.toJsonStr(list));
}
@Test
public void testQueryWithMutexListWithoutArgs(){
List<User> list = distributeCacheService.queryWithMutexListWithoutArgs("mutex:list011:", User.class, this::getUserListWithoutArgs, 60L, TimeUnit.SECONDS);
System.out.println(JSONUtil.toJsonStr(list));
}
@Test
public void testQuerySimpleDataWithMutexList(){
List<Integer> list = distributeCacheService.queryWithMutexList("mutex:list2:", 123, Integer.class, this::getIds, 60L, TimeUnit.SECONDS);
System.out.println(JSONUtil.toJsonStr(list));
}
@Test
public void testQuerySimpleDataWithMutexListWithoutArgs(){
List<Integer> list = distributeCacheService.queryWithMutexListWithoutArgs("mutex:list2012:", Integer.class, this::getIdsWithoutArgs, 60L, TimeUnit.SECONDS);
System.out.println(JSONUtil.toJsonStr(list));
}
/**
* 模拟带参数从数据库查询对象
*/
public User getUser(Long id){
return new User(id, "binghe");
}
/**
* 默认不带参数从数据库查询对象
*/
public User getUserWithoutArgs(){
return new User(1L, "binghe");
}
/**
* 模拟带参数查询从数据库对象列表
*/
public List<User> getUserList(String type){
return Arrays.asList(
new User(1L, "binghe001"),
new User(2L, "binghe002"),
new User(3L, "binghe003")
);
}
/**
* 模拟不带参数从数据库查询对象列表
*/
public List<User> getUserListWithoutArgs(){
return Arrays.asList(
new User(1L, "binghe001"),
new User(2L, "binghe002"),
new User(3L, "binghe003")
);
}
/**
* 模拟带参数从数据库查询简单数据类型数据
*/
public Integer getId(Integer id){
return id;
}
/**
* 模拟不带参数从数据库查询简单数据类型数据
*/
public Integer getIdWithoutArgs(){
return 0;
}
/**
* 模拟带参数从数据库查询简单数据类型数据列表
*/
public List<Integer> getIds(Integer id){
return Arrays.asList(0,0,0);
}
/**
* 模拟不带参数从数据库查询简单数据类型数据列表
*/
public List<Integer> getIdsWithoutArgs(){
return Arrays.asList(0,0,0);
}
}
本群的宗旨是给大家提供一个良好的技术学习交流平台,所以杜绝一切广告!由于微信群人满 100 之后无法加入,请扫描下方二维码先添加作者 “冰河” 微信(hacker_binghe),备注:学习加群
。
分享各种编程语言、开发技术、分布式与微服务架构、分布式数据库、分布式事务、云原生、大数据与云计算技术和渗透技术。另外,还会分享各种面试题和面试技巧。内容在 冰河技术 微信公众号首发,强烈建议大家关注。
定期分享各种编程语言、开发技术、分布式与微服务架构、分布式数据库、分布式事务、云原生、大数据与云计算技术和渗透技术。另外,还会分享各种面试题和面试技巧。
加入星球 冰河技术,可以获得本站点所有学习内容的指导与帮助。如果你遇到不能独立解决的问题,也可以添加冰河的微信:hacker_binghe, 我们一起沟通交流。另外,在星球中不只能学到实用的硬核技术,还能学习实战项目!
关注 冰河技术公众号,回复 星球
可以获取入场优惠券。
关注 冰河技术 微信公众号:
回复 “并发编程2” 领取《深入理解高并发编程(第2版)》PDF电子书。
回复 “并发编程” 领取《深入理解高并发编程(第1版)》PDF电子书。
回复 “并发源码” 领取《并发编程核心知识(源码分析篇 第1版)》PDF电子书。
回复 “并发路线” 领取并发编程高清学习路线。
回复 “SA实战” 领取《SpringCloud Alibaba实战》PDF电子书。
回复 “渗透笔记” 领取《冰河的渗透实战笔记》PDF电子书。
回复 “ngx2” 获取《Nginx核心技术手册》PDF电子书。
回复 “我要进大厂” 领取《我要进大厂系列之面试圣经(第1版)》PDF电子书。
回复 ”限流“ 领取《亿级流量下的分布式解决方案》PDF电子书。
回复 “设计模式” 领取《深入浅出Java23种设计模式》PDF电子书。
回复 “Java8新特性” 领取 《Java8新特性教程》PDF电子书。
回复 “分布式存储” 领取《跟冰河学习分布式存储技术》 PDF电子书。
回复 “Nginx” 领取《跟冰河学习Nginx技术》PDF电子书。
回复 “互联网工程” 领取《跟冰河学习互联网工程技术》PDF电子书。
回复 “冰河索引” 领取《冰河技术公号文章索引》PDF电子书。
回复 “星球” 获取知识星球优惠券 。
微信搜一搜【冰河技术】微信公众号,关注这个有深度的程序员,每天阅读超硬核技术干货,公众号内回复【PDF】有我准备的一线大厂面试资料和我原创的超硬核PDF技术文档,以及我为大家精心准备的多套简历模板(不断更新中),希望大家都能找到心仪的工作,学习是一条时而郁郁寡欢,时而开怀大笑的路,加油。如果你通过努力成功进入到了心仪的公司,一定不要懈怠放松,职场成长和新技术学习一样,不进则退。如果有幸我们江湖再见!
另外,我开源的各个PDF,后续我都会持续更新和维护,感谢大家长期以来对冰河的支持!!
回复【并发编程2】获取冰河最新整理的《深入理解高并发编程(第2版)》电子书。
回复【并发编程】获取全网累计下载60W+的《深入理解高并发编程》电子书。
回复【渗透笔记】获取全网5星好评的《冰河的渗透实战笔记》电子书。
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。