つまり、このキャッシュはスレッドセーフであり、LRU プロパティがあります。 CacheBuilder Guava Docsを参照してください。
私の仮定は、同じキーを持つ複数のスレッドが同時に起動された場合です。これには CyclicBarrier が使用され、1 つのスレッドが put() をキャッシュに入れ、他のスレッドは待機します。その後、残りのスレッドは、値がすでにキャッシュにあり、 put() がキャッシュにないことを確認します。
これは、各スレッドが新しい Object() を作成してキャッシュに入れるため、以下のコードには当てはまりません。テストを実行してコンソールを確認し、毎回異なるオブジェクトが作成されることを確認します。
CacheBuilderの使用方法に本質的に問題はありますか?- 私が使用できるより良い方法はありますか?
- 使用できるライブラリはありますか?
よろしくお願いします!
import java.util.concurrent.CyclicBarrier;
import org.junit.Test;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
public class GuavaLRUCacheTest {
private Cache<String, Object> concurrentLRUCache = CacheBuilder.newBuilder().maximumSize(100).concurrencyLevel(1).build();
@Test
public void test() throws Exception {
// The gate size is set based on the (number of threads to run) + (1 for the current thread).
CyclicBarrier gate = new CyclicBarrier(4);
// Same key is used for all threads
ConcurrentLRUTestThread t1 = new ConcurrentLRUTestThread(gate, "key1");
ConcurrentLRUTestThread t2 = new ConcurrentLRUTestThread(gate, "key1");
ConcurrentLRUTestThread t3 = new ConcurrentLRUTestThread(gate, "key1");
t1.start();
t2.start();
t3.start();
// Open the gate on all threads.
gate.await();
t1.join();
t2.join();
t3.join();
}
class ConcurrentLRUTestThread extends Thread {
private CyclicBarrier gate;
private String key;
public ConcurrentLRUTestThread(CyclicBarrier gate, String key) {
this.gate = gate;
this.key = key;
}
@Override
public void run() {
try {
gate.await();
if (concurrentLRUCache.getIfPresent(key) == null) {
System.out.println(">>>>> "+ System.nanoTime() +" - "+Thread.currentThread().getId() + " before put " + concurrentLRUCache.getIfPresent(key));
concurrentLRUCache.put(key, new Object());
System.out.println(">>>>> "+ System.nanoTime() +" - "+Thread.currentThread().getId() + " after put " + concurrentLRUCache.getIfPresent(key));
} else{
System.out.println(">>>>> "+ System.nanoTime() +" - "+Thread.currentThread().getId() + " else " + concurrentLRUCache.getIfPresent(key));
}
} catch (Throwable x) {
System.out.println(">>>>> "+ System.currentTimeMillis() +" - "+Thread.currentThread().getId() + " ConcurrentLRUTestThread exception");
}
}
}
}