缓存并发 RemovalListener
Cache concurrency RemovalListener
public class testCache {
static final Striped<Lock> lockStriped = Striped.lazyWeakLock(1024);
static final Cache<Integer, Holder> cache = CacheBuilder.newBuilder().concurrencyLevel(50).expireAfterAccess(10000l, TimeUnit.DAYS).maximumSize(5000)
.removalListener((RemovalListener<Integer, Holder>) removalNotification -> {
System.out.println("tests");
System.out.println(removalNotification.getCause());
System.out.println(removalNotification.getKey());
System.out.println(removalNotification.getValue());
}).build();
public static void main(String[] args) {
System.out.println("Starting");
ExecutorService executor = Executors.newFixedThreadPool(40);
for (int i = 0; i < 1000; i++) {
for (int j = 0; j < 1000; j++) {
int finalI = i;
executor.execute(() -> setCounter(finalI));
int finalI1 = i;
executor.execute(() -> setFlag(finalI1));
}
}
for (int i = 0; i < 1000; i++) {
cache.invalidate(i);
}
executor.shutdown();
while (!executor.isTerminated()) {
}
}
private static void setFlag(int id) {
Lock lock = lockStriped.get(id);
try {
lock.lock();
Holder holder = cache.getIfPresent(id);
if (holder == null) {
holder = new Holder();
holder.setFlag(true);
cache.put(id, holder);
} else {
holder.setFlag(id % 2 != 0);
}
} finally {
lock.unlock();
}
}
private static void setCounter(int id) {
Lock lock = lockStriped.get(id);
try {
lock.lock();
Holder holder = cache.getIfPresent(id);
if (holder == null) {
holder = new Holder();
int i = holder.getCounter() + 1;
holder.setCounter(i);
cache.put(id, holder);
} else {
int i = holder.getCounter() + 1;
holder.setCounter(i);
}
} finally {
lock.unlock();
}
}
}
您好,这是简单的代码。问题是为什么缓存中的某些值与我预期的不同。我认为 cahce 中应该有 1000 个条目,每个条目的计数器为 1000,但处理结束于
Holder{counter=1000, flag=false}
tests
EXPLICIT
105
Holder{counter=985, flag=true}
tests
EXPLICIT
106
Holder{counter=1000, flag=false}
tests
EXPLICIT
107
Holder{counter=717, flag=true}
问题出在哪里写这种测试的好方法或者我错过了什么。
更改代码
for (int i = 0; i < 1000; i++) {
cache.invalidate(i);
}
executor.shutdown();
while (!executor.isTerminated()) {}
至
executor.shutdown();
while (!executor.isTerminated()) {}
for (int i = 0; i < 1000; i++) {
cache.invalidate(i);
}
解决了我的问题
public class testCache {
static final Striped<Lock> lockStriped = Striped.lazyWeakLock(1024);
static final Cache<Integer, Holder> cache = CacheBuilder.newBuilder().concurrencyLevel(50).expireAfterAccess(10000l, TimeUnit.DAYS).maximumSize(5000)
.removalListener((RemovalListener<Integer, Holder>) removalNotification -> {
System.out.println("tests");
System.out.println(removalNotification.getCause());
System.out.println(removalNotification.getKey());
System.out.println(removalNotification.getValue());
}).build();
public static void main(String[] args) {
System.out.println("Starting");
ExecutorService executor = Executors.newFixedThreadPool(40);
for (int i = 0; i < 1000; i++) {
for (int j = 0; j < 1000; j++) {
int finalI = i;
executor.execute(() -> setCounter(finalI));
int finalI1 = i;
executor.execute(() -> setFlag(finalI1));
}
}
for (int i = 0; i < 1000; i++) {
cache.invalidate(i);
}
executor.shutdown();
while (!executor.isTerminated()) {
}
}
private static void setFlag(int id) {
Lock lock = lockStriped.get(id);
try {
lock.lock();
Holder holder = cache.getIfPresent(id);
if (holder == null) {
holder = new Holder();
holder.setFlag(true);
cache.put(id, holder);
} else {
holder.setFlag(id % 2 != 0);
}
} finally {
lock.unlock();
}
}
private static void setCounter(int id) {
Lock lock = lockStriped.get(id);
try {
lock.lock();
Holder holder = cache.getIfPresent(id);
if (holder == null) {
holder = new Holder();
int i = holder.getCounter() + 1;
holder.setCounter(i);
cache.put(id, holder);
} else {
int i = holder.getCounter() + 1;
holder.setCounter(i);
}
} finally {
lock.unlock();
}
}
}
您好,这是简单的代码。问题是为什么缓存中的某些值与我预期的不同。我认为 cahce 中应该有 1000 个条目,每个条目的计数器为 1000,但处理结束于
Holder{counter=1000, flag=false}
tests
EXPLICIT
105
Holder{counter=985, flag=true}
tests
EXPLICIT
106
Holder{counter=1000, flag=false}
tests
EXPLICIT
107
Holder{counter=717, flag=true}
问题出在哪里写这种测试的好方法或者我错过了什么。
更改代码
for (int i = 0; i < 1000; i++) {
cache.invalidate(i);
}
executor.shutdown();
while (!executor.isTerminated()) {}
至
executor.shutdown();
while (!executor.isTerminated()) {}
for (int i = 0; i < 1000; i++) {
cache.invalidate(i);
}
解决了我的问题