java.lang.IllegalMonitorStateException: Sync[state=-1; owner=Thread[TP-Processor51,5,main]]

Atlassian JIRA | Chris Fuller | 2 years ago
Do you know that we can give you better hits? Get more relevant results from Samebug’s stack trace search.
  1. 0

    Although it seems like a bizarre thing to do in the first place, the workarounds for CACHE-106 and CACHE-108 altered the behaviour when a cache's lazy loader invalidates itself. Both the Guava and EhCache implementations treat a loading entry as being non-existent and the remove is completely ignored, regardless of whether the request came from the same thread that is performing the load or not. But this is unacceptable because it allows stale data to enter the cache. The workaround creates a lock around the cache loading that the remove must wait on before it can actually do the removal. The problem is that if this thread is the one that is performing the load, then it cannot wait for the lock to clear, because it is the thread that owns the lock and this would be a self-deadlock, so when the thread attempts this, the result is an {{IllegalMonitorStateException}} with a trace something like this: {code} SEVERE: Servlet.service() for servlet action threw exception java.lang.IllegalMonitorStateException: Sync[state=-1; owner=Thread[TP-Processor51,5,main]] at com.atlassian.cache.impl.OneShotLatch$Sync.tryAcquireShared( at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireShared( at com.atlassian.cache.impl.OneShotLatch.await( at com.atlassian.cache.memory.BlockingCacheLoader.acquire( at com.atlassian.cache.memory.DelegatingCache$DelegatingLoadingCache.remove( at com.atlassian.cache.compat.jira.delegate.DelegatingCache.remove( at com.example.jira.plugin.ExampleComponent$CacheLoader.load( at com.atlassian.cache.compat.jira.delegate.DelegatingCacheLoader.load( at com.atlassian.cache.memory.MemoryCacheManager$3$1.load( at com.atlassian.cache.memory.BlockingCacheLoader.load( {code} It is possible to alter the locking code to restore the original behaviour of simply ignoring a {{remove}} iff the thread requesting it is also the thread that holds the lock, but: # Was the loader smart enough to correct its own return value, or is it going to put a stale value into the cache that its own {{remove}} call was meant to invalidate? We have no way of knowing. # It seems very strange for the {{CacheLoader}} to need to do a {{remove}} on its own value in the first place. It may be hard to establish consistent behaviour for something like this across the multiple implementations of the library that we have. It seems like a better idea to explicitly reject this as an acceptable request than to allow a pattern that we probably can't support consistently. My inclination is to close this as a Won't Fix.

    Atlassian JIRA | 2 years ago | Chris Fuller
    java.lang.IllegalMonitorStateException: Sync[state=-1; owner=Thread[TP-Processor51,5,main]]

    Root Cause Analysis

    1. java.lang.IllegalMonitorStateException

      Sync[state=-1; owner=Thread[TP-Processor51,5,main]]

      at com.atlassian.cache.impl.OneShotLatch$Sync.tryAcquireShared()
    2. com.atlassian.cache
      1. com.atlassian.cache.impl.OneShotLatch$Sync.tryAcquireShared(
      1 frame
    3. Java RT
      1. java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireShared(
      1 frame
    4. com.atlassian.cache
      1. com.atlassian.cache.impl.OneShotLatch.await(
      2. com.atlassian.cache.memory.BlockingCacheLoader.acquire(
      3. com.atlassian.cache.memory.DelegatingCache$DelegatingLoadingCache.remove(
      4. com.atlassian.cache.compat.jira.delegate.DelegatingCache.remove(
      4 frames
    5. com.example.jira
      1. com.example.jira.plugin.ExampleComponent$CacheLoader.load(
      1 frame
    6. com.atlassian.cache
      1. com.atlassian.cache.compat.jira.delegate.DelegatingCacheLoader.load(
      2. com.atlassian.cache.memory.MemoryCacheManager$3$1.load(
      3. com.atlassian.cache.memory.BlockingCacheLoader.load(
      3 frames