2017-06-20 28 views
0
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,但问题出在哪里是写这种测试还是我错过了什么好办法上缓存并发RemovalListener

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} 

处理结束。

回答

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

解决我的问题

+0

['做{}而(executor.awaitTermination(1,TimeUnit.DAYS)!);'( https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html#awaitTermination-long-java.util.concurrent.TimeUnit-)... – Holger