当前位置: 首页 > 知识库问答 >
问题:

Java上Redis散列中的列表

欧阳正德
2023-03-14
public void put(String hashName, int key , List<myObj> myList) {
        redis.opsForHash().put(hashName, String.valueOf(key), myList);
        }

public List<myObj> get(String hashName, string key) {
    Object map = redis.opsForHash().get(hashName,key);
    if (map==null) {
        log.info("no keys found");
        return new ArrayList<myObj>();
    }
    List<myObj> myList= mapper.convertValue(map, new TypeReference<List<myObj>(){});
    return myList;
}

执行更新的操作是:

List<myObj> myList= hash.get(hashName,key);
myList.add(obj);
hash.put(hashName, key, myList);

当有多个实例时,我出现在竞争条件下。有没有一种方法以原子的方式更新列表值?

共有1个答案

云和硕
2023-03-14

您当前的实现并不好,因为在put()中您更新了整个列表。如果许多线程想要向列表中添加一个元素,它们首先获得当前列表,然后添加一个元素,然后放入新的列表。每个线程将重写前一个线程的结果,最后一个线程获胜。synchronized的用法在这里无关紧要。

解决方案

不要替换整个列表。相反,向列表中添加一个元素。删除put()方法,并添加一个新方法,如下所示:

public synchronized void add(String hashName, int key, myObj element) {
    List<myObj> myList;
    Object map = redis.opsForHash().get(hashName,key);
    if (map != null) {
        myList= mapper.convertValue(map, new TypeReference<List<myObj>(){});
    } else {
        myList = new ArrayList<myObj>();
    }
    myList.add(element);
    redis.opsForHash().put(hashName, String.valueOf(key), myList);
}
public List<myObj> get(String hashName, string key) {
    Object map = redis.opsForHash().get(hashName,key);
    if (map==null) {
        log.info("no keys found");
        return new ArrayList<myObj>();
    }
    List<myObj> myList= mapper.convertValue(map, new TypeReference<List<myObj>(){});
    return Collections.unmodifiableList(myList);
}
 类似资料:
  • 主要内容:初识hash类型,常用命令汇总,基本命令操作Redis hash(哈希散列)是由字符类型的 field(字段)和 value 组成的哈希映射表结构(也称散列表),它非常类似于表格结构。在 hash 类型中,field 与 value 一一对应,且不允许重复。 Redis hash 特别适合于存储对象。一个 filed/value 可以看做是表格中一条数据记录;而一个 key 可以对应多条数据。下面举一个例子,使用 hash 类型存储表格中的

  • 我正在用java编写一个小程序,根据netflow数据为防火墙创建访问列表。 简而言之,我有一个名为< code > sourceAggregatedFlows 的hashmap,它包含作为键的源IP组(自定义对象)和作为值的目的IP地址 在我的代码中,我需要迭代源IP组,并确定键值中的目标地址是否与我搜索的地址匹配。 我注意到一个问题,有时遍历键集会在值上产生一个nullpointer异常。我已

  • 是否可以在不需要其他字段的情况下更新学生对象的单个字段?假设我想更新年级字段。

  • 考虑 HashSet 作为一个 HashMap,在此处我们只关心键(HashSet<T> 实际上只是一个包围 HashMap<T, ()> 的装包(wrapper))。(原文:Consider a HashSet as a HashMap where we just care about the keys (HashSet<T> is, in actuality, just a wrapper a

  • 问题内容: 我想将JSON有效负载存储到Redis中。我确实有2种方法可以做到这一点: 一种使用简单的字符串键和值。 键:用户,值:有效载荷(整个JSON Blob,可以为100-200 KB) 使用哈希 请记住,如果使用散列,则值长度是不可预测的。它们并不都是短的,例如上面的bio示例。 哪个内存效率更高?使用字符串键和值,还是使用哈希? 问题答案: 这取决于您如何访问数据: 选择选项1: 如果

  • 根据关键码值(Key value)直接进行访问的数据结构;它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度;这个映射函数叫做散列函数,存放记录的数组叫做散列表。