> For the complete documentation index, see [llms.txt](https://ysfang82.gitbook.io/development-notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ysfang82.gitbook.io/development-notes/programming-langauges/java/cache.md).

# Cache

### refresh vs expire

* Refresh and expire can exist at the same time. Entries queried with longer life than expire limit would trigger `load()` , and entries queried with longer life than refresh limit would trigger `reload()` accordingly.
* When entry is expired, `get()` would trigger `load()` and block until `load()` is complete.
* Entry runs `reload()` when its life is longer than refresh limit and gets invoked of `call()` .
* Event entry gets `load()` or `reload()`, the time they get into cache would not be updated.

```
public static void main(String[] args) throws InterruptedException {
    LoadingCache<String, String> ca = Caffeine.newBuilder()
            .expireAfterWrite(Duration.ofMillis(1000)) // Set to 800 to trigger load()
            .refreshAfterWrite(Duration.ofMillis(800))
            .build(new CacheLoader<String, String>() {
        @Override
        public @Nullable String load(String key) throws Exception {
            return "load_" + key;
        }

        @Override
        public @Nullable String reload(String key, String oldValue) throws Exception {
            return "reload_" + key;
        }
    });
    ca.put("a", "A");
    int millisSleep = 300;
    System.out.println("ca.get(\"a\") = " + ca.get("a"));
    for (int i = 1; i <= 5; i++) {
        System.out.println("millis: " + i * millisSleep);
        Thread.sleep(millisSleep);
        System.out.println("ca.get(\"a\") = " + ca.get("a"));
        System.out.println("ca.get(\"a\") = " + ca.get("a"));
    }
}
```
