java – Couchbase:从静态代码块中初始化需要更长时间
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java – Couchbase:从静态代码块中初始化需要更长时间,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3569字,纯文字阅读大概需要6分钟。
内容图文

我把我的couchbase初始化代码放在静态代码块中:
static {
initCluster();
bucket = initBucket("graph");
metaBucket = initBucket("meta");
BLACKLIST = new SetObservingCache<String>(() -> getBlackList(), BLACKLIST_REFRESH_INTERVAL_SEC * 1000);
}
我知道这不是一个好习惯,但它非常方便并且达到了它的目的,因为我需要这个代码在多线程环境中运行一次并阻止来自其他线程的所有后续调用,直到它完成(黑名单已初始化).
令我惊讶的是,对getBlacklist()的调用超时并且无法完成.
但是,在2分钟后再次调用它时(这就是ObservingCache的功能),它在不到一秒的时间内就完成了.
为了解决这个问题,我重构了我的代码并使黑名单获取变得懒惰:
public boolean isBlacklisted(String key) {
// BLACKLIST variable should NEVER be touched outside of this context.
assureBlacklistIsPopulated();
return BLACKLIST != null ? BLACKLIST.getItems().contains(key) : false;
}
private void assureBlacklistIsPopulated() {
if (!ENABLE_BLACKLIST) {
return;
}
if (BLACKLIST == null) {
synchronized (CouchConnectionManager.class) {
if (BLACKLIST == null) {
BLACKLIST = new SetObservingCache<String>(() -> getBlackList(), BLACKLIST_REFRESH_INTERVAL_SEC * 1000);
}
}
}
}
对isBlacklisted()的调用会阻止所有其他线程尝试检查条目是否被列入黑名单,直到黑名单被初始化.
我不是这个解决方案的忠实粉丝,因为它非常冗长且容易出错 – 有人可能会尝试从BLACKLIST读取而不事先调用assureBlacklistIsPopulated().
类中的静态(和非最终)字段如下:
private static CouchbaseCluster cluster;
private static Bucket bucket;
private static Bucket metaBucket;
private static SetObservingCache<String> BLACKLIST;
当它不是静态初始化块的一部分时,我无法弄清楚调用成功的原因.我不知道静态初始化块有任何已知的与性能相关的漏洞吗?
编辑:为每个请求添加初始化代码
private Bucket initBucket(String bucketName) {
while(true) {
Throwable t = null;
try {
ReportableThread.updateStatus("Initializing bucket " + bucketName);
return cluster.openBucket(bucketName);
} catch(Throwable t1) {
t1.printStackTrace();
t = t1;
}
try {
ReportableThread.updateStatus(String.format("Failed to open bucket: %s reason: %s", bucketName, t));
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void initCluster() {
CouchbaseEnvironment env = DefaultCouchbaseEnvironment
.builder()
.kvTimeout(MINUTE)
.connectTimeout(MINUTE)
.retryStrategy(FailFastRetryStrategy.INSTANCE)
.requestBufferSize(16384 * 2)
.responseBufferSize(16384 * 2)
.build();
while(true) {
ReportableThread.updateStatus("Initializing couchbase cluster");
Throwable t = null;
try {
cluster = CouchbaseCluster.create(env, getServerNodes());
if(cluster != null) {
return;
}
} catch(Throwable t1) {
t1.printStackTrace();
t = t1;
}
try {
ReportableThread.updateStatus(String.format("Failed to create connection to couch %s", t));
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public Set<String> getBlackList() {
ReportableThread.updateStatus("Getting black list");
AbstractDocument<?> abstractDoc = get("blacklist", metaBucket, JsonArrayDocument.class);
JsonArrayDocument doc = null;
if (abstractDoc != null && abstractDoc instanceof JsonArrayDocument) {
doc = (JsonArrayDocument)abstractDoc;
} else {
return new HashSet<String>();
}
ReportableThread.updateStatus(String.format("%s: Got %d items | sorting items", new Date(System.currentTimeMillis()).toString(), doc.content().size()));
HashSet<String> ret = new HashSet<String>();
for (Object string : doc.content()) {
if (string != null) {
ret.add(string.toString());
}
}
return ret;
}
解决方法:
第一:你正在做双重检查的成语.这总是很糟糕.
只放一个if(BLACKLIST == null)并且它必须在synchronized中.
第二:懒惰初始化很好,但是在静态getInstance()中执行它并且永远不要公开BLACKLIST字段.
内容总结
以上是互联网集市为您收集整理的java – Couchbase:从静态代码块中初始化需要更长时间全部内容,希望文章能够帮你解决java – Couchbase:从静态代码块中初始化需要更长时间所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。