首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用get和put作为原子操作使并发散列映射线程安全?

如何使用get和put作为原子操作使并发散列映射线程安全?
EN

Stack Overflow用户
提问于 2016-11-27 17:33:54
回答 2查看 1.1K关注 0票数 2

下面的方法线程安全吗?此方法在Singleton类中。

代码语言:javascript
运行
复制
  private static final Map<String, PreparedStatement> holder = new ConcurrentHashMap<>();

  public BoundStatement getStatement(String cql) {
    Session session = TestUtils.getInstance().getSession();
    PreparedStatement ps = holder.get(cql);
    if(ps == null) { // If "ps" is already present in cache, then we don't have to synchronize and make threads wait.
        synchronized {
          ps = holder.get(cql);
          if (ps == null) {
            ps = session.prepare(cql);
            holder.put(cql, ps);
          }
        }
    }
    return ps.bind();
  }

我正在使用Cassandra并使用datastax驱动程序,所以我重用准备好的语句,这就是我在这里缓存它的原因。准备陈述BoundStatement.

有什么更好的方法来使我的getStatement方法线程安全(如果它是线程安全的话),而不是像这样使用同步块?对于这类操作,是否还有线程安全的其他数据结构?我正在使用Java 7。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-11-27 17:56:05

由于.putIfAbsent在Java7中,所以可以使用它:

代码语言:javascript
运行
复制
 private static final ConcurrentHashMap<String, PreparedStatement> holder = new ConcurrentHashMap<>();

  public BoundStatement getStatement(String cql) {
    Session session = TestUtils.getInstance().getSession();
    PreparedStatement ps = holder.get(cql);
    if(ps == null) { // If "ps" is already present in cache, then we don't have to synchronize and make threads wait.

         if (holder.putIfAbsent(cql, session.prepare(cql)) != null) {
            // Someone else got there before, handle
         }
    }
    return ps.bind();
  }

注意,putIfAbsent在内部仍然使用相同的同步。

票数 3
EN

Stack Overflow用户

发布于 2016-11-28 12:05:13

如果您想做某种形式的回忆录,那么这是您在Java 7中能够做的最好/最简单的方法。番石榴有一个可以使用的计算缓存实现,而Java 8在Map接口中有一个Map方法,但显然您在这里运气不佳。

如果你能在一个空的竞赛中创建对象,就像Alexey的答案所建议的那样,这将是最好的解决方案。如果不能,您的实现是线程安全和合理的。

这是一种双重检查锁定的形式,但是,在使用CHM的putget方法进行排序之前,您将确保发生这种情况。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40831817

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档