代码之家  ›  专栏  ›  技术社区  ›  jstur

为什么在Vertx的车把库中调用Synchronize?

  •  0
  • jstur  · 技术社区  · 7 年前

    我想知道为什么 synchronized 此方法中使用了来自Vertx手把库的块 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));
        }
    }
    

    请跟我解释一下,好像我是个白痴!

    1 回复  |  直到 7 年前
        1
  •  1
  •   Alexey Soshin    7 年前

    首先,同步问题绝不是“白痴”问题。
    我也花了一些时间研究了这段代码,但仍然不能100%确定它是完全正确的。

    最主要的原因是 synchronized 这里的块是为了防止以下两种方法执行不正常:

    loader.setPrefix(prefix);
    ...
    template = handlebars.compile(basename);
    

    你看,车把指的是装载机:

    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