这是一个用Netty实现的,支持多线程和异步调用,lock-free 的JavaRedis client客户端
(服务器版本:https://blog.csdn.net/pp634077956/article/details/82178710)
github: https://github.com/pyb1993/JavaRedisClient
目的1 配合JavaRedis服务器进行调试
目的2 用来学习各种异步回调/future的机制
目的3 用来学习线程安全的问题
目前实现的功能:
1. 同步调用
2. 异步调用 + future回调(可以嵌套使用)
3. 多线程 同步 异步 调用
4. 连接池缓存(超时无效)
看代码的思路:
1 首先看初始化RedisClient的过程
2 然后看异步命令 getAsync 的逻辑
包括 连接的获取,编码/解码,handler的处理
3 然后看同步命令 get的逻辑
大致脉络就搞明白了
使用的方法
同步使用:
@Test
public void getSetTest(){
int connNum = 100000;
CountDownLatch c = new CountDownLatch(connNum);//todo XXXX
RedisClient client = new RedisClient("127.0.0.1", 3333);
for(int i = 0; i < connNum; ++i){
String value = "第" + i + "次";
client.set(i + "",value);
String result = client.get(i + "");
assert result.equals(value);
}
}
异步调用
@Test
public void asyncGetSetTest() throws Exception{
//Logger.setDebug();
int connNum = 10000;
CountDownLatch c = new CountDownLatch(connNum);//todo XXXX
try (RedisClient client = new RedisClient("127.0.0.1", 3333)) {
// todo 配置化,从配置文件导入(需要在配置文件里面写出来 命令,对应的response类型名字)
testForOne(client,c,connNum);
}
c.await();
RedisClient.stop();//
}
/**
* 用来执行异步测试,将被其它测试接口调用
* client, countDownLatch c(用来进行同步,确保所有回调执行完)
* **/
private void testForOne(RedisClient client,CountDownLatch c,int taskLoad){
for (int _i = 0; _i < taskLoad; _i++) {
final int i = _i;
String val = "你好,master" + _i;
client.setAsync(_i + "",val ).addListener(future -> {
RedisFuture r = client.getAsync(i + "");
r.addListener(f -> {
c.countDown();
String result = (String)f.get();
assert result.equals(val);
});
});
};
}
解释: 实际上就是传统的回调写法,注意addListener
实际上是Netty提供的,如果添加很多listener
,它会一个接着一个执行,而且listener
里面不能写阻塞操作,所以如果里面有异步操作,就只能回调嵌套回调。