我使用RegionShortcut.PARTITION和setRedundantCopies(1)定义了GemFire区域。 在3个不同的虚拟机上运行的3个应用程序正在利用这些区域。
当我关闭刚刚将项目插入缓存的应用程序的VM(项目的“所有者”)时,似乎我有一个死锁:
*被阻止的进程:在region.put之前被阻止。
*阻止进程:尝试从区域中删除旧条目后似乎被阻止。我怀疑此操作是由CacheListenerAdapter提供的销毁机制调用的。
我在以下链接中阅读了有关此问题的一些文档: CacheListener Interface API和blog主要发现了听众的使用责任。
然而,似乎这些问题已在GemFire 6.x版本中得到解决和修复[例如:here和here]
所以,我想问一下:
1)Gemfire 8报告了这个问题吗?还是7?
2)这个问题的推荐解决方法是什么?提到了3种不同的解决方法here。还有别的吗?任何首选的?
仅供参考,阻止进程的线程转储如下:
Owner stack trace: java.lang.Throwable
at sun.misc.Unsafe.park(Native Method)
at java.util.concurrent.locks.LockSupport.park(Unknown Source)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(Unknown Source)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(Unknown Source)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(Unknown Source)
at java.util.concurrent.locks.ReentrantReadWriteLock$ReadLock.lockInterruptibly(Unknown Source)
at com.gemstone.gemfire.internal.cache.BucketRegion.lockPrimaryStateReadLock(BucketRegion.java:780)
at com.gemstone.gemfire.internal.cache.BucketRegion.doLockForPrimary(BucketRegion.java:719)
at com.gemstone.gemfire.internal.cache.BucketRegion.beginLocalWrite(BucketRegion.java:704)
at com.gemstone.gemfire.internal.cache.BucketRegion.basicDestroy(BucketRegion.java:1105)
at com.gemstone.gemfire.internal.cache.PartitionedRegionDataStore.destroyLocally(PartitionedRegionDataStore.java:1511)
at com.gemstone.gemfire.internal.cache.PartitionedRegion.destroyInBucket(PartitionedRegion.java:5440)
at com.gemstone.gemfire.internal.cache.PartitionedRegionDataView.destroyExistingEntry(PartitionedRegionDataView.java:45)
at com.gemstone.gemfire.internal.cache.PartitionedRegion.basicDestroy(PartitionedRegion.java:5317)
at com.gemstone.gemfire.internal.cache.LocalRegion.validatedDestroy(LocalRegion.java:1330)
at com.gemstone.gemfire.internal.cache.LocalRegion.destroy(LocalRegion.java:1317)
at com.gemstone.gemfire.internal.cache.AbstractRegion.destroy(AbstractRegion.java:282)
at com.gemstone.gemfire.internal.cache.LocalRegion.remove(LocalRegion.java:9513)
答案 0 :(得分:1)
涉及CacheListeners的死锁是可能的。该行为记录在最新的(GemFire 8.1)javadoc中。以下是CacheListener文档的相关摘录:
避免死锁风险
在对EntryEvent描述的条目进行锁定时调用CacheListener上的方法,因此如果侦听器方法需要很长时间才能执行,那么它将导致调用它的操作被调用很久。另外,调用Region方法的侦听器代码可能会导致死锁。例如,在用于条目密钥k1的afterUpdate(EntryEvent)中,在用于条目密钥k2调用put(k1,someVal)的Update(EntryEvent)之后同时调用put(k2,someVal),可能导致死锁。该共同密钥依赖性示例可以扩展到共同区域依赖性,其中区域" A"中的侦听器代码。在" B"上执行区域操作和" B"中的监听器代码;在" A"上执行区域操作。死锁可以是java级或分布式多VM死锁,具体取决于Region配置。为了确保没有死锁,侦听器代码应该导致其他一些线程访问该区域,并且不能等待该线程完成任务。