资讯专栏INFORMATION COLUMN

聊聊Elasticsearch的RunOnce

lindroid / 2531人阅读

摘要:序本文主要研究一下的实现了接口,它的构造器要求输入,同时构造了变量方法会先使用将由设置为,如果成功则执行代理的的方法方法则返回值实例方法验证了顺序多次执行的场景方法则验证了并发多次执行的场景则验证了使用作为的场景小结实现了接口,它的构

本文主要研究一下Elasticsearch的RunOnce

RunOnce

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

public class RunOnce implements Runnable {

    private final Runnable delegate;
    private final AtomicBoolean hasRun;

    public RunOnce(final Runnable delegate) {
        this.delegate = Objects.requireNonNull(delegate);
        this.hasRun = new AtomicBoolean(false);
    }

    @Override
    public void run() {
        if (hasRun.compareAndSet(false, true)) {
            delegate.run();
        }
    }

    /**
     * {@code true} if the {@link RunOnce} has been executed once.
     */
    public boolean hasRun() {
        return hasRun.get();
    }
}

RunOnce实现了Runnable接口,它的构造器要求输入Runnable,同时构造了hasRun变量;run方法会先使用compareAndSet将hasRun由false设置为true,如果成功则执行代理的Runnable的run方法;hasRun方法则返回hasRun值

实例

elasticsearch-7.0.1/server/src/test/java/org/elasticsearch/common/util/concurrent/RunOnceTests.java

public class RunOnceTests extends ESTestCase {

    public void testRunOnce() {
        final AtomicInteger counter = new AtomicInteger(0);
        final RunOnce runOnce = new RunOnce(counter::incrementAndGet);
        assertFalse(runOnce.hasRun());

        runOnce.run();
        assertTrue(runOnce.hasRun());
        assertEquals(1, counter.get());

        runOnce.run();
        assertTrue(runOnce.hasRun());
        assertEquals(1, counter.get());
    }

    public void testRunOnceConcurrently() throws InterruptedException {
        final AtomicInteger counter = new AtomicInteger(0);
        final RunOnce runOnce = new RunOnce(counter::incrementAndGet);

        final Thread[] threads = new Thread[between(3, 10)];
        final CountDownLatch latch = new CountDownLatch(1);
        for (int i = 0; i < threads.length; i++) {
            threads[i] = new Thread(() -> {
                try {
                    latch.await();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                runOnce.run();
            });
            threads[i].start();
        }

        latch.countDown();
        for (Thread thread : threads) {
            thread.join();
        }
        assertTrue(runOnce.hasRun());
        assertEquals(1, counter.get());
    }

    public void testRunOnceWithAbstractRunnable() {
        final AtomicInteger onRun = new AtomicInteger(0);
        final AtomicInteger onFailure = new AtomicInteger(0);
        final AtomicInteger onAfter = new AtomicInteger(0);

        final RunOnce runOnce = new RunOnce(new AbstractRunnable() {
            @Override
            protected void doRun() throws Exception {
                onRun.incrementAndGet();
                throw new RuntimeException("failure");
            }

            @Override
            public void onFailure(Exception e) {
                onFailure.incrementAndGet();
            }

            @Override
            public void onAfter() {
                onAfter.incrementAndGet();
            }
        });

        final int iterations = randomIntBetween(1, 10);
        for (int i = 0; i < iterations; i++) {
            runOnce.run();
            assertEquals(1, onRun.get());
            assertEquals(1, onFailure.get());
            assertEquals(1, onAfter.get());
            assertTrue(runOnce.hasRun());
        }
    }
}

testRunOnce方法验证了顺序多次执行runOnce的场景;testRunOnceConcurrently方法则验证了并发多次执行runOnce的场景;testRunOnceWithAbstractRunnable则验证了使用AbstractRunnable作为runnable的场景

小结

RunOnce实现了Runnable接口,它的构造器要求输入Runnable,同时构造了hasRun变量;run方法会先使用compareAndSet将hasRun由false设置为true,如果成功则执行代理的Runnable的run方法;hasRun方法则返回hasRun值

doc

RunOnce

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/34487.html

相关文章

  • Android5.1.1源码 - zygote fork出子进程如何权限降级

    摘要:子进程权限降级函数函数在文件中,在这个函数中调用了函数,并且出的子进程将自身权限降级,下面是它的源码在这个函数中子进程分别调用了,设置了组和用户将自身权限降级。 前言 如果不知道zygote是什么,或者好奇zygote如何启动,可以去看老罗的文章: Android系统进程Zygote启动过程的源代码分析 所有Android应用进程都是zygote fork出来的,新fork出来的应用进...

    wua_wua2012 评论0 收藏0
  • 聊聊ElasticsearchExponentiallyWeightedMovingAverage

    摘要:序本文主要研究一下的实现了,它是线程安全的其构造器要求输入及越大表示新数据权重越大旧数据权重越小返回的是的值,不过它存储的是的形式,返回的时候使用转换会方法使用计算新值,然后使用方法来实现原子更新实例方法测试算法的计算逻辑测试 序 本文主要研究一下Elasticsearch的ExponentiallyWeightedMovingAverage ExponentiallyWeighted...

    Tony_Zby 评论0 收藏0
  • 聊聊ElasticsearchReleasables

    摘要:序本文主要研究一下的继承了接口提供静态方法用于更方便地使用实例在中使用关闭了小结提供静态方法用于更方便地使用 序 本文主要研究一下Elasticsearch的Releasables Releasable elasticsearch-7.0.1/server/src/main/java/org/elasticsearch/common/lease/Releasable.java publ...

    null1145 评论0 收藏0
  • 聊聊ElasticsearchConcurrentMapLong

    摘要:序本文主要研究一下的继承了接口,并指定类型为实现了接口,它内部使用实现提供了及两个静态方法用于创建其中方法创建为,为,为的小结继承了接口,并指定类型为实现了接口,它内部使用实现提供了及两个静态方法用于创建其中方法创建为,为,为的 序 本文主要研究一下Elasticsearch的ConcurrentMapLong ConcurrentMapLong elasticsearch-7.0.1...

    lidashuang 评论0 收藏0
  • 聊聊ElasticsearchBootstrapCheck

    摘要:序本文主要研究一下的接口定义了方法,该方法返回,另外还定义了一个方法,默认返回的方法返回了一系列,其中包括等要求不得小于要求是对开启的话要求是以后,避免小结接口定义了方法,该方法返回,另外还定义了一个方法,默认返回的方法返回了一 序 本文主要研究一下Elasticsearch的BootstrapCheck BootstrapCheck elasticsearch-7.0.1/serve...

    Alex 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<