Caffeine 结合了调度器和执行器服务

如何解决Caffeine 结合了调度器和执行器服务

我在以下配置中使用咖啡因:

    Cache<String,String> cache = caffeine.newBuilder()
                .executor(newWorkStealingPool(15))
                .scheduler(createScheduler())
                .expireAfterWrite(10,TimeUnit.SECONDS)
                .maximumSize(MAXIMUM_CACHE_SIZE)
                .removalListener(this::onRemoval)
                .build();


    private Scheduler createScheduler() {
        return forscheduledexecutorservice(newSingleThreadScheduledExecutor());
    }

我是否正确地假设 onRemoval 方法将在 newWorkStealingPool(15) ForkJoinPool 上执行,并且只会调用调度程序来查找需要驱逐的过期条目?

意味着它会像这样:

  1. 调用单线程调度程序(每约 1 秒)
  2. 找到所有要驱逐的过期条目
  3. 为缓存构建器中定义的 newWorkStealingPool(15) 中的每个被驱逐的条目执行 onRemoval

我没有找到解释这种行为的文档,所以我在这里

Tnx

解决方法

您的假设很接近,只是在实践中稍微优化了一些。

  1. 缓存读取和写入在底层哈希表上执行并附加到内部环形缓冲区。
  2. 当缓冲区达到阈值时,会将任务提交给 Caffeine.executor 以调用 Cache.cleanUp
  3. 当此维护周期运行时(处于锁定状态),
    • 缓冲区被排空,事件根据驱逐策略重播(例如 LRU 重新排序)
    • 丢弃任何可驱逐的条目,并将任务提交给 Caffeine.executor 以调用 RemovalListener.onRemoval
    • 下一个条目到期之前的持续时间是 calculated 并提交给调度程序。这由 pacer 保护,因此通过确保在计划任务之间发生 ~1s 来避免过度计划。
  4. 当调度程序运行时,一个任务被提交到 Caffeine.executor 以调用 Cache.cleanUp(参见 #3)。

调度程序执行最少的工作,任何处理都推迟到执行程序。由于使用 O(1) 算法,维护工作很便宜,因此它可能经常根据使用活动发生。它针对小批量工作进行了优化,因此在计划调用之间强制执行约 1 秒的延迟有助于每次调用捕获更多工作。如果下一个过期事件发生在遥远的未来,那么调度程序将在此之前不会运行,尽管调用线程可能会由于它们在缓存上的活动而触发维护周期(参见 #1,2)。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?