将 "get/check/put" 的使用替换为 putIfAbsent
Replace use of "get/check/put" with putIfAbsent
我正在使用 Cassandra 并使用 Datastax Java 驱动程序。我正在尝试通过缓存来重用准备好的语句。
private static final Map<String, PreparedStatement> holder = new ConcurrentHashMap<>();
public BoundStatement getStatement(String cql) {
Session session = TestUtils.getInstance().getSession();
PreparedStatement ps = holder.get(cql);
// no statement is cached, create one and cache it now.
if (ps == null) {
synchronized (this) {
ps = holder.get(cql);
if (ps == null) {
ps = session.prepare(cql);
holder.put(cql, ps);
}
}
}
return ps.bind();
}
我上面的 getStatement
方法将被多个线程调用,所以我必须确保它是线程安全的。我正在使用 Java 7,所以很遗憾不能使用 computeIfAbsent
。
当我 运行 我的代码针对静态分析工具时,它给了我这个小警告,这让我想在 Java 7 中有没有更好的方法来编写上面的代码?
Might be better to replace use of get/check/put with putIfAbsent
更新:
public BoundStatement getStatement(String cql) {
Session session = TestUtils.getInstance().getSession();
PreparedStatement ps = holder.get(cql);
// no statement is cached, create one and cache it now.
if (ps == null) {
ps = session.prepare(cql);
PreparedStatement old = holder.putIfAbsent(cql, ps);
if (old!=null)
ps=old;
}
return ps.bind();
}
你拥有它的方式并不算太糟糕,除了一个线程可以阻塞另一个线程,即使它们没有尝试制作相同的准备好的语句。
在Java8中使用computeIfAbsent
确实会好很多。在Java7中,你可以这样做:
ps = holder.get(cql);
if (ps == null) {
ps = session.prepare(cql);
PreparedStatement old = holder.putIfAbsent(cql, ps);
if (old!=null)
ps=old;
}
如果两个线程同时尝试创建相同的 PreparedStatement,您偶尔会创建一个不必要的 PreparedStatement,但在最坏的情况下,这相当于不使用缓存。
或者,如果您可以使用 guava 库,则 guava LoadingCache 会完全满足您的要求:https://google.github.io/guava/releases/16.0/api/docs/com/google/common/cache/CacheBuilder.html
我正在使用 Cassandra 并使用 Datastax Java 驱动程序。我正在尝试通过缓存来重用准备好的语句。
private static final Map<String, PreparedStatement> holder = new ConcurrentHashMap<>();
public BoundStatement getStatement(String cql) {
Session session = TestUtils.getInstance().getSession();
PreparedStatement ps = holder.get(cql);
// no statement is cached, create one and cache it now.
if (ps == null) {
synchronized (this) {
ps = holder.get(cql);
if (ps == null) {
ps = session.prepare(cql);
holder.put(cql, ps);
}
}
}
return ps.bind();
}
我上面的 getStatement
方法将被多个线程调用,所以我必须确保它是线程安全的。我正在使用 Java 7,所以很遗憾不能使用 computeIfAbsent
。
当我 运行 我的代码针对静态分析工具时,它给了我这个小警告,这让我想在 Java 7 中有没有更好的方法来编写上面的代码?
Might be better to replace use of get/check/put with putIfAbsent
更新:
public BoundStatement getStatement(String cql) {
Session session = TestUtils.getInstance().getSession();
PreparedStatement ps = holder.get(cql);
// no statement is cached, create one and cache it now.
if (ps == null) {
ps = session.prepare(cql);
PreparedStatement old = holder.putIfAbsent(cql, ps);
if (old!=null)
ps=old;
}
return ps.bind();
}
你拥有它的方式并不算太糟糕,除了一个线程可以阻塞另一个线程,即使它们没有尝试制作相同的准备好的语句。
在Java8中使用computeIfAbsent
确实会好很多。在Java7中,你可以这样做:
ps = holder.get(cql);
if (ps == null) {
ps = session.prepare(cql);
PreparedStatement old = holder.putIfAbsent(cql, ps);
if (old!=null)
ps=old;
}
如果两个线程同时尝试创建相同的 PreparedStatement,您偶尔会创建一个不必要的 PreparedStatement,但在最坏的情况下,这相当于不使用缓存。
或者,如果您可以使用 guava 库,则 guava LoadingCache 会完全满足您的要求:https://google.github.io/guava/releases/16.0/api/docs/com/google/common/cache/CacheBuilder.html