聊聊Elasticsearch的LazyInitializable

本文主要研究一下Elasticsearch的LazyInitializable

LazyInitializable

elasticsearch-7.0.1/server/src/main/java/org/elasticsearch/common/util/LazyInitializable.java

public final class LazyInitializable<T, E extends Exception> {

    private final CheckedSupplier<T, E> supplier;
    private final Consumer<T> onGet;
    private final Consumer<T> onReset;
    private volatile T value;

    /**
     * Creates the simple LazyInitializable instance.
     *
     * @param supplier
     *            The {@code CheckedSupplier} to generate values which will be
     *            served on {@code #getOrCompute()} invocations.
     */
    public LazyInitializable(CheckedSupplier<T, E> supplier) {
        this(supplier, v -> {}, v -> {});
    }

    /**
     * Creates the complete LazyInitializable instance.
     *
     * @param supplier
     *            The {@code CheckedSupplier} to generate values which will be
     *            served on {@code #getOrCompute()} invocations.
     * @param onGet
     *            A {@code Consumer} which is called on each value, newly forged or
     *            stale, that is returned by {@code #getOrCompute()}
     * @param onReset
     *            A {@code Consumer} which is invoked on the value that will be
     *            erased when calling {@code #reset()}
     */
    public LazyInitializable(CheckedSupplier<T, E> supplier, Consumer<T> onGet, Consumer<T> onReset) {
        this.supplier = supplier;
        this.onGet = onGet;
        this.onReset = onReset;
    }

    /**
     * Returns a value that was created by <code>supplier</code>. The value might
     * have been previously created, if not it will be created now, thread safe of
     * course.
     */
    public T getOrCompute() throws E {
        final T readOnce = value; // Read volatile just once...
        final T result = readOnce == null ? maybeCompute(supplier) : readOnce;
        onGet.accept(result);
        return result;
    }

    /**
     * Clears the value, if it has been previously created by calling
     * {@code #getOrCompute()}. The <code>onReset</code> will be called on this
     * value. The next call to {@code #getOrCompute()} will recreate the value.
     */
    public synchronized void reset() {
        if (value != null) {
            onReset.accept(value);
            value = null;
        }
    }

    /**
     * Creates a new value thread safely.
     */
    private synchronized T maybeCompute(CheckedSupplier<T, E> supplier) throws E {
        if (value == null) {
            value = Objects.requireNonNull(supplier.get());
        }
        return value;
    }

}
复制代码
  • LazyInitializable封装了CheckedSupplier,类似CachedSupplier,不过它提供了reset方法可以重置以反复使用,另外还支持了onGet、onReset的回调

实例

elasticsearch-7.0.1/plugins/discovery-ec2/src/main/java/org/elasticsearch/discovery/ec2/AwsEc2ServiceImpl.java

class AwsEc2ServiceImpl implements AwsEc2Service {
    
    private static final Logger logger = LogManager.getLogger(AwsEc2ServiceImpl.class);

    private final AtomicReference<LazyInitializable<AmazonEc2Reference, ElasticsearchException>> lazyClientReference =
            new AtomicReference<>();

    //......
    
    public void refreshAndClearCache(Ec2ClientSettings clientSettings) {
        final LazyInitializable<AmazonEc2Reference, ElasticsearchException> newClient = new LazyInitializable<>(
                () -> new AmazonEc2Reference(buildClient(clientSettings)), clientReference -> clientReference.incRef(),
                clientReference -> clientReference.decRef());
        final LazyInitializable<AmazonEc2Reference, ElasticsearchException> oldClient = this.lazyClientReference.getAndSet(newClient);
        if (oldClient != null) {
            oldClient.reset();
        }
    }

    //......
}        
复制代码
  • AwsEc2ServiceImpl的refreshAndClearCache方法会根据clientSettings创建新的LazyInitializable,之后更新lazyClientReference,如果oldClient不为null则调用其reset方法重置value

小结

LazyInitializable封装了CheckedSupplier,类似CachedSupplier,不过它提供了reset方法可以重置以反复使用,另外还支持了onGet、onReset的回调

doc

转载于:https://juejin.im/post/5cfbba6051882512d72f2c03

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
《狂神聊Elasticsearch.md》是一篇关于Elasticsearch的文章。Elasticsearch是一个开源的分布式搜索和分析引擎,它被广泛应用于全文搜索、数据分析、日志处理等场景。这篇文章详细介绍了Elasticsearch的原理、基本操作和常用功能。 文章首先介绍了Elasticsearch的基本概念和架构。它采用分布式的倒排索引,以实现高效的全文搜索。集群中的每个节点都可以承担不同的角色,包括主节点、数据节点和协调节点。这种设计使得Elasticsearch具有高可用性和弹性伸缩性。 接下来,文章详细介绍了如何安装和配置Elasticsearch。它提供了两种安装方式,一种是通过官方下载安装包进行安装,另一种是通过Docker容器进行安装。然后,文章介绍了如何配置Elasticsearch的参数,包括网络配置、集群配置和节点配置等。 文章还介绍了Elasticsearch的常用功能,包括索引管理、数据查询、聚合分析和文档更新等。通过示例代码和详细讲解,读者可以了解到如何创建索引、添加文档、执行查询和聚合操作。文章还介绍了如何使用Kibana进行数据可视化和监控。 最后,文章提到了Elasticsearch的一些高级功能,包括分布式搜索、索引优化和集群监控等。它介绍了如何通过查询路由和复制机制实现分布式搜索,并讲解了如何通过分片和副本优化索引的性能和可靠性。此外,文章还介绍了如何使用Elasticsearch的API和插件进行集群监控和故障诊断。 总之,这篇文章全面而详细地介绍了Elasticsearch的原理、操作和常用功能,对于想要学习和使用Elasticsearch的人来说,是一篇非常有价值的参考资料。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值