缓存并发RemovealListener

时间:2017-06-20 22:43:09

标签: java concurrency guava google-guava-cache

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}

问题出在哪里这是写这种测试的好方法,或者我错过了什么。

1 个答案:

答案 0 :(得分:0)

更改代码

   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);
}

解决了我的问题