//从第1个开始,依次向左插入值。如果键不存在,先创建再插入值  队列形式 先进后出,后进先出
//插入后形式  <-- 10,9,8,7,6,5,4,3,2,1 <-- 方向向左依次进行
stopwatch.Start();
for (int i = ; i < ; i++)
{
var getobjlist = RedisCacheHelper.Instance.ListLeftPush("leftlistkey", (i + ).ToString());
}
stopwatch.Stop();
Console.WriteLine("在列表头部插入值消耗时间:" + stopwatch.ElapsedMilliseconds.ToString()); //从第1个开始,依次向右插入值。如果键不存在,先创建再插入值 先进先出,后进后出
//插入后形式  1,2,3,4,5,6,7,8,9,10 --> 方向向右依次进行
stopwatch.Start();
for (int i = ; i < ; i++)
{
var getobjlist = RedisCacheHelper.Instance.ListRightPush("rightlistkey", (i + ).ToString());
}
stopwatch.Stop();
Console.WriteLine("在列表尾部插入值消耗时间:" + stopwatch.ElapsedMilliseconds.ToString());

            //获取Left列表中的队列元素  从列表头部开始读取
var getleftvalue = RedisCacheHelper.Instance.ListRange("leftlistkey");
Console.WriteLine(string.Join(",", getleftvalue)); //获取Right列表中的队列元素 从列表头部开始读取
var getrightvalue = RedisCacheHelper.Instance.ListRange("rightlistkey");
Console.WriteLine(string.Join(",", getrightvalue));

            //从左边第一个元素开始  循环移除并返回该移除的值
Console.WriteLine("从左边开始");
while (true)
{
var getleftvalue = RedisCacheHelper.Instance.ListLeftPop("leftlistkey");
if (!string.IsNullOrEmpty(getleftvalue))
{
Console.WriteLine("移除:" + getleftvalue);
}
else
{
break;
}
} //从右边第一个元素开始 循环移除并返回该移除的值
Console.WriteLine("从右边开始");
while (true)
{
var getrightvalue = RedisCacheHelper.Instance.ListRightPop("rightlistkey");
if (!string.IsNullOrEmpty(getrightvalue))
{
Console.WriteLine("移除:" + getrightvalue);
}
else
{
break;
}
}

            //从左边第一个元素开始  循环移除并返回该移除的值  替换一下Key后
Console.WriteLine("从左边开始");
while (true)
{
var getleftvalue = RedisCacheHelper.Instance.ListLeftPop("rightlistkey");
if (!string.IsNullOrEmpty(getleftvalue))
{
Console.WriteLine("移除:" + getleftvalue);
}
else
{
break;
}
} //从右边第一个元素开始 循环移除并返回该移除的值 替换一下Key后
Console.WriteLine("从右边开始");
while (true)
{
var getrightvalue = RedisCacheHelper.Instance.ListRightPop("leftlistkey");
if (!string.IsNullOrEmpty(getrightvalue))
{
Console.WriteLine("移除:" + getrightvalue);
}
else
{
break;
}
}

            //列表长度  不存在则返回0
var getlength = RedisCacheHelper.Instance.ListLength("leftlistkey");
Console.WriteLine("列表长度:" + getlength); //删除List中的元素 并返回删除的个数 不存在则返回0
var getlong = RedisCacheHelper.Instance.ListDelRange("leftlistkey", "");
Console.WriteLine("删除List中的元素,并返回删除的个数:" + getlong); //清空列表
RedisCacheHelper.Instance.ListClear("leftlistkey");

使用List类型 模拟用户并发抢购商品

//模拟数据  想List类型表中加入一定数量的库存   50个商品
for (int i = ; i <= ; i++)
{
var getvalue = RedisCacheHelper.Instance.ListRightPush("orderlist", i.ToString());
//Console.WriteLine("返回结果:" + getvalue);
} //模拟创建多个用户 100个用户
List<TestRedis> testlist = new List<TestRedis>();
for (int i = ; i < ; i++)
{
testlist.Add(new TestRedis() { Uid = (i + ) });
} //先清空
RedisCacheHelper.Instance.ListClear("orderSuccessList"); //使用List类型模拟并发情况 不用担心库存为负的情况
//模拟多个用户抢购限时商品 100个用户抢50个商品
stopwatch.Start();
List<Task> taskList = new List<Task>();
foreach (var item in testlist)
{
var task = Task.Run(() =>
{
try
{
//先自减,获取自减后的值
long order_Num = -;
long.TryParse(RedisCacheHelper.Instance.ListRightPop("orderlist"), out order_Num);
if (order_Num > )
{
//下面执行订单逻辑(这里不考虑业务出错的情况) RedisCacheHelper.Instance.ListLeftPush("orderSuccessList", item.Uid.ToString()); //记录下单成功的用户 //操作数据库相关逻辑 可以使用“消息队列”或“服务”进行数据库同步操作 Console.WriteLine("用户:" + item.Uid + ",抢到了商品:" + order_Num);
}
else
{
Console.WriteLine("商品已经被抢光了,用户" + item.Uid + "未抢到");
} }
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw;
}
});
taskList.Add(task);
}
Task.WaitAll(taskList.ToArray());
stopwatch.Stop();
Console.WriteLine("模拟并发场景消耗时间:" + stopwatch.ElapsedMilliseconds.ToString());

应用场景:

Redis list 的应用场景非常多,也是 Redis 最重要的数据结构之一,比如 twitter 的关注列表,粉丝列表等都可以用 Redis 的 list 结构来实现,比较好理解,这里不再重复。

实现方式:

Redis list 的实现为一个双向链表,即可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销,Redis 内部的很多实现,包括发送缓冲队列等也都是用的这个数据结构。

最后附上Helper

        /// <summary>
/// 在列表头部插入值。如果键不存在,先创建再插入值
/// </summary>
/// <param name="redisKey"></param>
/// <param name="redisValue"></param>
/// <returns></returns>
public long ListLeftPush(string redisKey, string redisValue, int db = -)
{
var _db = GetDatabase(db);
return _db.ListLeftPush(redisKey, redisValue);
}
/// <summary>
/// 在列表尾部插入值。如果键不存在,先创建再插入值
/// </summary>
/// <param name="redisKey"></param>
/// <param name="redisValue"></param>
/// <returns></returns>
public long ListRightPush(string redisKey, string redisValue, int db = -)
{
var _db = GetDatabase(db);
return _db.ListRightPush(redisKey, redisValue);
} /// <summary>
/// 在列表尾部插入数组集合。如果键不存在,先创建再插入值
/// </summary>
/// <param name="redisKey"></param>
/// <param name="redisValue"></param>
/// <returns></returns>
public long ListRightPush(string redisKey, IEnumerable<string> redisValue, int db = -)
{
var _db = GetDatabase(db);
var redislist = new List<RedisValue>();
foreach (var item in redisValue)
{
redislist.Add(item);
}
return _db.ListRightPush(redisKey, redislist.ToArray());
} /// <summary>
/// 移除并返回存储在该键列表的第一个元素 反序列化
/// </summary>
/// <param name="redisKey"></param>
/// <returns></returns>
public T ListLeftPop<T>(string redisKey, int db = -) where T : class
{
var _db = GetDatabase(db);
return JsonConvert.DeserializeObject<T>(_db.ListLeftPop(redisKey));
} /// <summary>
/// 移除并返回存储在该键列表的最后一个元素 反序列化
/// 只能是对象集合
/// </summary>
/// <param name="redisKey"></param>
/// <returns></returns>
public T ListRightPop<T>(string redisKey, int db = -) where T : class
{
var _db = GetDatabase(db);
return JsonConvert.DeserializeObject<T>(_db.ListRightPop(redisKey));
} /// <summary>
/// 移除并返回存储在该键列表的第一个元素
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="redisKey"></param>
/// <param name="db"></param>
/// <returns></returns>
public string ListLeftPop(string redisKey, int db = -)
{
var _db = GetDatabase(db);
return _db.ListLeftPop(redisKey);
} /// <summary>
/// 移除并返回存储在该键列表的最后一个元素
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="redisKey"></param>
/// <param name="db"></param>
/// <returns></returns>
public string ListRightPop(string redisKey, int db = -)
{
var _db = GetDatabase(db);
return _db.ListRightPop(redisKey);
} /// <summary>
/// 列表长度
/// </summary>
/// <param name="redisKey"></param>
/// <param name="db"></param>
/// <returns></returns>
public long ListLength(string redisKey, int db = -)
{
var _db = GetDatabase(db);
return _db.ListLength(redisKey);
} /// <summary>
/// 返回在该列表上键所对应的元素
/// </summary>
/// <param name="redisKey"></param>
/// <returns></returns>
public IEnumerable<string> ListRange(string redisKey, int db = -)
{
var _db = GetDatabase(db);
var result = _db.ListRange(redisKey);
return result.Select(o => o.ToString());
} /// <summary>
/// 根据索引获取指定位置数据
/// </summary>
/// <param name="redisKey"></param>
/// <param name="start"></param>
/// <param name="stop"></param>
/// <param name="db"></param>
/// <returns></returns>
public IEnumerable<string> ListRange(string redisKey, int start, int stop, int db = -)
{
var _db = GetDatabase(db);
var result = _db.ListRange(redisKey, start, stop);
return result.Select(o => o.ToString());
} /// <summary>
/// 删除List中的元素 并返回删除的个数
/// </summary>
/// <param name="redisKey">key</param>
/// <param name="redisValue">元素</param>
/// <param name="type">大于零 : 从表头开始向表尾搜索,小于零 : 从表尾开始向表头搜索,等于零:移除表中所有与 VALUE 相等的值</param>
/// <param name="db"></param>
/// <returns></returns>
public long ListDelRange(string redisKey, string redisValue, long type = , int db = -)
{
var _db = GetDatabase(db);
return _db.ListRemove(redisKey, redisValue, type);
} /// <summary>
/// 清空List
/// </summary>
/// <param name="redisKey"></param>
/// <param name="db"></param>
public void ListClear(string redisKey, int db = -)
{
var _db = GetDatabase(db);
_db.ListTrim(redisKey, , );
}

最新文章

  1. Oracle VM VirtualBox 安装CentOS 配置图形界面记录
  2. PHP-CS-Fixer:格式化你的PHP代码
  3. 3到6年的.NETer应该掌握哪些知识?
  4. try-catch 示例
  5. 转:bash: /dev/null: Permission denied
  6. YII Framework学习教程-YII的异常处理
  7. 【转】Myeclipse8.5 反编译插件 jad 安装
  8. Node.js权威指南 (14) - 使用Express构建Web应用程序
  9. excel取值
  10. Please read “Security” section of the manual to find out how to run mysqld as root!错误解决(转)
  11. 【CentOS】阿里云ECS申请CA证书配置SSL
  12. jquery左右折叠框
  13. nopcommerce 4.1 core 插件 相关1
  14. js-运动函数(盒子运动)
  15. [LeetCode] Backtracking Template for (Subsets, Permutations, and Combination Sum)
  16. OSGI企业应用开发(十二)OSGI Web应用开发(一)
  17. mysql database 格式的查看和改变
  18. Java实习一
  19. 高阶篇:4.2.3)DFMEA现有设计:预防控制与探测控制
  20. 阿冰教你一步一步做Android新闻客户端(二)两种异步线程加载图片的方法

热门文章

  1. Oracle GoldenGate 19.1新特性
  2. 去除空白字符串trim
  3. ERR : undefined reference to something
  4. node js 爬啊爬 记录 向 Scott 致敬 不要问为什么
  5. php---&gt;使用callable强制指定回调类型
  6. 关于Windows Server 服务器 安装tomcat部署Java Web 项母
  7. JVM性能分析 | 一次生产系统Full GC问题分析与排查总结
  8. Arduino系列之光照传感器(三)
  9. NetModular 新年第一更以及升级指南(打造简单易用的.Net Core模块化快速开发框架~)
  10. Spring使用外部属性文件