Redis教程

redis锁,Map

本文主要是介绍redis锁,Map,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

redis数据类型
String:jedis.set(key,“value”);
List:jedis.lpush(“listkey01”,“张三”,“李四”,“王五”);
redis锁
StringRedisTemplate工具类
opsForValue().setIfAbsent方法中设置key,value,超时时间,并且返回值,如果key中有值那么返回false,如果key在redis中没有值那么返回true;
在finally中删除:异常时未被删除;
超时时间:宕机时未被删除;
设置唯一value:不同线程的redis互删;A线程超时,自动删除key,超时但是还是成功执行了finally中又删了一次。
添加并发线程:线程超时时,自动给这个线程续时间。
redis锁抽奖大致逻辑
获取所有状态正常的奖品,分成两种抽奖,一种是每天只允许抽限量数目,生成限制数量的时间点,在那个时间点之后的第一个用户抽得奖品,这里需要使用redis锁住修改奖品状态,并保存到数据库中。一种是抽奖按照原先设定的概率来抽,因为奖品的数量需要不断的查询,将奖品的查询作为缓存放到redis中,提高效率。为了尽可能的锁住少一点代码。这里不使用锁锁住,当奖品有存货的时候直接按照概率开始抽奖。如果有部分奖品没有存货,那么有存货的奖品按照原有概率按照占有比例去抽奖。抽的奖品后,使用redis锁锁住,获取redis当前数量,并且减一,存到数据库中。若当前redis数量没了。赋予某种便宜的奖品。
hashMap
1、创建数组在调用第一个put的时候;
2、为什么数组的长度是2的幂;
在底层hashcode是二进制做位运算的。位的加减就是乘2除2;
3、扩容机制:
hashcode没有碰撞时,通过hashcode的值一步到位找到值的位置。当数据变多难免产生碰撞,碰撞就导致寻找一些数据除了hashcode一步到位,还要在链表上查找,一步变两步,而且还是在链表上一个一个找。所以尽量避免碰撞,但是也不能无节制的将数组变大。所以经过大量的实验和计算得出0.75这个中间值。
4、jdk1.7的hashmap头插法无限循环问题。
举例:X桶中有两个节点A,B。A.next为B。此时在并发的情况下做扩容,A保存完A.next开始把A放到另一个数组中时,当前线程的时间片停住了。而另外一个线程已经完成A与B的转移。在新的桶中,B.next指向了A。A指向NULL。可是在旧的线程中已经保存了A.next指向B。那么就变成了A.NEXT指向B,B.next指向A。无限循环中了。
5、JDK1.8的hashmap高低位数组。
遍历桶中的链表结构时,创建高位头部,尾部指针,低位头部,尾部指针。将0的放到低位数组中,1的放到高位数组中。没有提前保存.next无论是否并发,都会按固有顺序排列好后放到新的桶中。
ConcurrentHashMap
hashTable:直接整个表上锁,效率低下。
jdk1.7ConcurrentHashMap
分段锁:put时创建两种hash表。一种是整体数组,一种是小段数组。整体由这些小段数组组成。这些小段数组继承自ReentranLock。拥有锁的特质。在小段数组中的元素共享一把锁,同一段数组内的数据插入时需要获取锁。锁的粒度锁住的是这一小锻数据,效率比hashTable高的多。
jdk1.8ConcurrentHashMap
插入第二元素时再给单个元素加锁。
当插入数据时,判断该桶中是否存在数据,如果不存在数据使用cas插入数据。插入成功则成功,插入失败则重来。重来时往往就直到当前桶中已经由其他数据了。就会锁住当前这个桶,进行操作。这种方式效率高。碰撞本不就不是大概率时间,再者其锁的粒度只针对单个桶元素。其效率超高。

这篇关于redis锁,Map的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!