我正在尝试实现“缓存条目丰富”行为:
以下代码实现了这一点,但是显然很糟糕。有没有一种方法可以通过纯缓存配置来实现?
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListenableFutureTask;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import lombok.SneakyThrows;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class GuavaCacheTest {
final LoadingCache<Long, String> myCache = CacheBuilder.newBuilder()
.maximumSize(1000)
.build(
new CacheLoader<Long, String>() {
ExecutorService executor = Executors.newFixedThreadPool(10);
public String load(Long key) {
System.out.println("load() " + key);
return "INITIAL";
}
public ListenableFuture<String> reload(final Long key, String prevString) {
// asynchronous!
ListenableFutureTask<String> task = ListenableFutureTask.create(() -> {
System.out.println("reload() started for ... " + key);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("reload() ended for ... " + key);
return "Calculated value for " + key;
});
executor.execute(task);
return task;
}
});
public String myget(Long key) {
String v = myCache.getUnchecked(key);
if (v == "INITIAL") {
myCache.refresh(key);
myCache.getUnchecked(key);
v = "Initial value for " + key;
}
return v;
}
@Test
@SneakyThrows
public void testRepeatedCalls() {
System.out.println("Call result: " + myget(55L));
System.out.println("Call result: " + myget(55L));
System.out.println("Call result: " + myget(55L));
System.out.println("Call result: " + myget(55L));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("---------------");
System.out.println("Call result: " + myget(55L));
System.out.println("Call result: " + myget(55L));
System.out.println("Call result: " + myget(55L));
System.out.println("Call result: " + myget(55L));
}
}
load() 55
reload() started for ... 55
Call result: Initial value for 55
Call result: Initial value for 55
Call result: Initial value for 55
Call result: Initial value for 55
reload() ended for ... 55
---------------
Call result: Calculated value for 55
Call result: Calculated value for 55
Call result: Calculated value for 55
Call result: Calculated value for 55