使用装饰器的简单缓存机制

阿卜杜拉萨克灵魂:

我有一个简单的界面

public interface Text {

    String asText() throws IOException;
}

和一个实现

public final class TextFromFile implements Text{

    private final String path;

    public TextFromFile(final String pth) {
        this.path = pth;
    }

    @Override
    public String asText() throws IOException {
        final String text = Files.readAllLines(Paths.get(this.path))
                                 .stream()
                                 .collect(Collectors.joining(""));
        return text;
    }

}

此类非常简单,它从文件中读取文本,然后将其作为字符串返回。为了避免多次读取文件,我想创建第二个类来装饰原始类

public final class CachedText implements Text{

    private final Text origin;

    private String result;

    public CachedText(final Text orgn) {
        this.origin = orgn;
    }

    @Override
    public String asText() throws IOException {
        if(this.result == null){
            this.result = this.origin.asText();
        }
        return this.result;
    }

}

现在它起作用了;但是,它result是可变的,并且为了与多个线程正常工作,我创建了另一个装饰器

public final class ThreadSafeText implements Text{

    private final Text origin;

    public ThreadSafeText(final Text orgn) {
        this.origin = orgn;
    }



    @Override
    public String asText() throws IOException {
        synchronized(this.origin){
            return this.origin.asText();
        }
    }

}

但是现在我的程序每次调用都会在同步上花费资源asText()

在我的情况下,缓存机制的最佳实现是什么?

Rann Lifshitz:

我建议通过Double Check Lock机制使您的缓存类同步,而不是为了线程安全而使用其他实现:

public final class CachedText implements Text{

    private final Text origin;

    private String result;

    public CachedText(final Text orgn) {
        this.origin = orgn;
    }

    @Override
    public String asText() throws IOException {
        if(this.result == null){
            synchronized(this) {
                if(this.result == null){
                    this.result = this.origin.asText();
                }
            }
        }
        return this.result;
    }

}

有可能是使用DCL所看到的关注在这里 -但如果他们在你的结束,只是评论存在,我会发布更多的支持(我相信,现代JVM更好地适合于处理的DCL)。

这应该满足您的需求。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章