2

我用 RegionShortcut.PARTITION 和 setRedundantCopies(1) 定义了一个 GemFire 区域。在 3 个不同的 VM 上运行的 3 个应用程序正在使用这些区域。

当我关闭刚刚将项目插入缓存的应用程序的虚拟机(项目的“所有者”)时,我似乎有一个死锁:

*被阻塞的进程:在region.put之前被阻塞。

*阻止过程:在尝试从区域中删除旧条目后似乎被阻止。我怀疑这个操作是被CacheListenerAdapter提供的销毁机制调用的。

我在以下链接中阅读了一些关于这个问题的文档: CacheListener Interface API和这个博客,主要发现了监听器的使用。

然而,这个问题似乎在 GemFire 6.x 版本中得到解决和修复 [例如:这里这里]

所以,我想问一下:

1) 是否针对 Gemfire 8 报告了此问题?还是7?

2)针对此问题推荐的解决方法是什么?这里提到了 3 种不同的解决方法。还有其他的吗?有首选吗?

仅供参考,阻塞进程的线程转储如下:

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)
4

1 回答 1

1

涉及 CacheListener 的死锁是可能的。该行为记录在最新的 (GemFire 8.1) javadoc 中。以下是 CacheListener 文档的相关摘录:

避免死锁的风险

CacheListener 上的方法在对由 EntryEvent 描述的条目保持锁定的同时被调用,因此,如果侦听器方法需要很长时间才能执行,那么它会导致导致它被调用的操作需要很长时间。此外,调用 Region 方法的侦听器代码可能会导致死锁。例如,在 entry key k1 的 afterUpdate(EntryEvent) 中,put(k2, someVal) 被调用,而 entry key k2 的 afterUpdate(EntryEvent) 调用 put(k1, someVal) 可能会导致死锁。这个 co-key 依赖关系示例可以扩展到一个 co-Region 依赖关系,其中区域“A”中的侦听器代码对“B”执行区域操作,而区域“B”中的侦听器代码对“A”执行区域操作。死锁可能是 java 级别或分布式多 VM 死锁,具体取决于区域配置。为了确保没有死锁,侦听器代码应该使其他线程访问该区域,并且不能等待该线程完成任务。

于 2015-06-30T18:44:23.713 回答