如何通过get和put作为原子操作使并发哈希映射线程安全? [英] How to make concurrent hash map thread safe with get and put as an atomic operation?

查看:219
本文介绍了如何通过get和put作为原子操作使并发哈希映射线程安全?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的以下方法线程安全吗?此方法在Singleton类中.

Is my below method thread safe? This method is in Singleton class.

  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 java驱动程序,所以我在重用准备好的语句,这就是为什么在这里缓存它.

I am working with Cassandra and using datastax java driver so I am reusing prepared statements and that's why I am caching it here. Prepared Statement and BoundStatement.

有没有更好的方法使我的getStatement方法线程安全(如果它是线程安全的),而不是像这样使用同步块?任何其他对于此类操作可能是线程安全的数据结构?我正在使用Java 7.

Is there any better way of making my getStatement method thread safe (if it is thread safe) instead of using synchronized block like that? Any other data structure which might be thread safe for these kind of operations? I am working with Java 7.

推荐答案

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

Since .putIfAbsent is in Java7, you can use it:

 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在内部仍使用相同的同步.

Note that putIfAbsent still uses same synchronization internally.

这篇关于如何通过get和put作为原子操作使并发哈希映射线程安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆