我们正在使用ehcache 2.9.0的应用程序。最近我们每周观察一次与ehcache get / put操作相关的死锁,一旦我们清除了缓存,问题就会消失。
我们在缓存获取操作期间观察RandomAccessFile上的锁定,并在放置操作期间观察ReentrantReadWriteLock。
请求ehcache专家了解可能出现的问题?
PFB来自线程转储的线程
" HTTP938" #25950 daemon prio = 5 os_prio = 0 tid = 0x0000000002614000 nid = 0x5a64等待条件[0x00007fcd36965000] java.lang.Thread.State:WAITING(停车) 在sun.misc.Unsafe.park(原生方法) - 停车等待< 0x00000005cbbc6768> (java.util.concurrent.locks.ReentrantReadWriteLock $ NonfairSync) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836) at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireShared(AbstractQueuedSynchronizer.java:967) at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireShared(AbstractQueuedSynchronizer.java:1283) at java.util.concurrent.locks.ReentrantReadWriteLock $ ReadLock.lock(ReentrantReadWriteLock.java:727) 在net.sf.ehcache.store.disk.Segment.flush(Segment.java:1010) 在net.sf.ehcache.store.disk.DiskStore.flush(DiskStore.java:248) at net.sf.ehcache.store.CacheStore $ 1.evicted(CacheStore.java:99) at net.sf.ehcache.store.CacheStore $ 1.evicted(CacheStore.java:96) at net.sf.ehcache.store.cachingtier.OnHeapCachingTier $ 1.evicted(OnHeapCachingTier.java:86) at net.sf.ehcache.store.cachingtier.CountBasedBackEnd $ 1.removed(CountBasedBackEnd.java:103) at net.sf.ehcache.util.concurrent.ConcurrentHashMap.internalReplace(ConcurrentHashMap.java:1346) at net.sf.ehcache.util.concurrent.ConcurrentHashMap.removeAndNotify(ConcurrentHashMap.java:2647) 在net.sf.ehcache.store.cachingtier.CountBasedBackEnd.remove(CountBasedBackEnd.java:115) 在net.sf.ehcache.store.cachingtier.OnHeapCachingTier.remove(OnHeapCachingTier.java:206) 在net.sf.ehcache.store.CacheStore.put(CacheStore.java:134) 在net.sf.ehcache.Cache.putInternal(Cache.java:1600) 在net.sf.ehcache.Cache.put(Cache.java:1526) 在net.sf.ehcache.Cache.put(Cache.java:1491) 在org.springframework.cache.ehcache.EhCacheCache.put(EhCacheCache.java:82) 在org.springframework.cache.interceptor.AbstractCacheInvoker.doPut(AbstractCacheInvoker.java:82) 在org.springframework.cache.interceptor.CacheAspectSupport $ CachePutRequest.apply(CacheAspectSupport.java:651) 在org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:358) 在org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:299) 在org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:61) 在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 在org.springframework.aop.framework.CglibAopProxy $ DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653)
" HTTP927" #25855 daemon prio = 5 os_prio = 0 tid = 0x00007fce685c9000 nid = 0x4fb6等待监视器条目[0x00007fcd359e8000] java.lang.Thread.State:BLOCKED(在对象监视器上) 在net.sf.ehcache.store.disk.DiskStorageFactory.read(DiskStorageFactory.java:362) - 等待锁定< 0x00000005cbdfb538> (java.io.RandomAccessFile) 在net.sf.ehcache.store.disk.DiskStorageFactory.retrieve(DiskStorageFactory.java:864) 在net.sf.ehcache.store.disk.Segment.decode(Segment.java:171) 在net.sf.ehcache.store.disk.Segment.remove(Segment.java:644) 在net.sf.ehcache.store.disk.DiskStore.remove(DiskStore.java:625) 在net.sf.ehcache.store.CacheStore.remove(CacheStore.java:236) at net.sf.ehcache.Cache.removeInternal(Cache.java:2401) at net.sf.ehcache.Cache.tryRemoveImmediately(Cache.java:2162) 在net.sf.ehcache.Cache.get(Cache.java:1739) 在org.springframework.cache.ehcache.EhCacheCache.get(EhCacheCache.java:65) 在org.springframework.cache.interceptor.AbstractCacheInvoker.doGet(AbstractCacheInvoker.java:68) 在org.springframework.cache.interceptor.CacheAspectSupport.findInCaches(CacheAspectSupport.java:461) 在org.springframework.cache.interceptor.CacheAspectSupport.findCachedItem(CacheAspectSupport.java:432) 在org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:333) 在org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:299) 在org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:61) 在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 在org.springframework.aop.framework.CglibAopProxy $ DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653)
线程HTTP762 拥有Monitor Lock on 0x00000005cbdfb538 在java.io.RandomAccessFile.readFully(RandomAccessFile.java:416) - 已锁定[0x00000005cbdfb538](java.io.RandomAccessFile) 在org.springframework.cache.ehcache.EhCacheCache.put(EhCacheCache.java:82) 谢谢, Nivedita
答案 0 :(得分:0)
我可能会遗漏一些东西,但我看不到你正在展示的线程转储中的任何死锁。只有两个线程在等待不同的东西,但没有等待另一个线程。
第一次尝试必须逐出一个值。
第二个线程注意到一个条目已过期,正在从磁盘存储中删除。
您是否确定磁盘本身或缓存中的数据结构导致磁盘速度变慢?
我还建议转到版本2.10.4,这可能会使问题消失。