为什么在vertx的Handlebars库中调用了Synchronize?
Why is Synchronize called in vertx's Handlebars library?
我试图理解为什么 synchronized
块用于来自 vertx handlebars 库的方法 io.vertx.ext.web.templ.handlebars.impl.HandlebarsTemplateEngineImpl class:
@Override
public void render(Map<String, Object> context, String templateFile, Handler<AsyncResult<Buffer>> handler) {
try {
int idx = templateFile.lastIndexOf('/');
String prefix = "";
String basename = templateFile;
if (idx != -1) {
prefix = templateFile.substring(0, idx);
basename = templateFile.substring(idx + 1);
}
Template template = isCachingEnabled() ? cache.get(templateFile) : null;
if (template == null) {
synchronized (this) {
loader.setPrefix(prefix);
// Strip leading slash from Utils##normalizePath
template = handlebars.compile(basename);
if (isCachingEnabled()) {
cache.put(templateFile, template);
}
}
}
Context engineContext = Context.newBuilder(context).resolver(getResolvers()).build();
handler.handle(Future.succeededFuture(Buffer.buffer(template.apply(engineContext))));
} catch (Exception ex) {
handler.handle(Future.failedFuture(ex));
}
}
请像我是白痴一样向我解释!
首先,同步问题从来都不是 "idiot" 问题。
我也花了一些时间查看这段代码,但仍然不能 100% 确定它是完全正确的。
这里有synchronized
块的主要原因是为了防止以下两个方法执行乱序:
loader.setPrefix(prefix);
...
template = handlebars.compile(basename);
你看,Handlebars 引用了加载程序:
loader = new Loader(vertx);
...
handlebars = new Handlebars(loader);
没有同步块的可能情况是
T1 sets prefix to A and switches
T2 sets prefix to B and switches
T1 compiles template with prefix set to B, while thinking it's still A
我试图理解为什么 synchronized
块用于来自 vertx handlebars 库的方法 io.vertx.ext.web.templ.handlebars.impl.HandlebarsTemplateEngineImpl class:
@Override
public void render(Map<String, Object> context, String templateFile, Handler<AsyncResult<Buffer>> handler) {
try {
int idx = templateFile.lastIndexOf('/');
String prefix = "";
String basename = templateFile;
if (idx != -1) {
prefix = templateFile.substring(0, idx);
basename = templateFile.substring(idx + 1);
}
Template template = isCachingEnabled() ? cache.get(templateFile) : null;
if (template == null) {
synchronized (this) {
loader.setPrefix(prefix);
// Strip leading slash from Utils##normalizePath
template = handlebars.compile(basename);
if (isCachingEnabled()) {
cache.put(templateFile, template);
}
}
}
Context engineContext = Context.newBuilder(context).resolver(getResolvers()).build();
handler.handle(Future.succeededFuture(Buffer.buffer(template.apply(engineContext))));
} catch (Exception ex) {
handler.handle(Future.failedFuture(ex));
}
}
请像我是白痴一样向我解释!
首先,同步问题从来都不是 "idiot" 问题。
我也花了一些时间查看这段代码,但仍然不能 100% 确定它是完全正确的。
这里有synchronized
块的主要原因是为了防止以下两个方法执行乱序:
loader.setPrefix(prefix);
...
template = handlebars.compile(basename);
你看,Handlebars 引用了加载程序:
loader = new Loader(vertx);
...
handlebars = new Handlebars(loader);
没有同步块的可能情况是
T1 sets prefix to A and switches
T2 sets prefix to B and switches
T1 compiles template with prefix set to B, while thinking it's still A