-
Bug
-
Resolution: Fixed
-
P3
-
5.0
-
b59
-
generic
-
generic
The JSR-166 expert group has found and fixed a number of issues with
ReentrantReadWriteLock:
Email excerpts follow:
>Ok this is a major one :(
But easy to fix!
>> " Acquires the shared lock.
Now phrased as variants of...
Acquires the read lock if the write lock is not held by another thread ...
All appropriate occurrences of "the lock" are now qualified with read
or write.
David:
>> Also in newCondition: the two class names should be in code font, I believe.
>> And the @return should say that it never returns normally.
fixed.
>I still don't know exactly how barging may or may not impact the RWL. :(
By strange coincidence, that c-i post bug report discovered the case
where the code doesn't meet the spec. So now it really IS a major
issue! (Well, the fix was obvious, but very embarassing that I had
messed up fairness vs reentrance checks.) Could you review the
change?
Martin: You probably didn't see this mail. Could you put in a
bug report?
>> From: Jon Rowland <###@###.###>
>> Sender: ###@###.###
>> To: ###@###.###
>> Cc: Jon Rowland <###@###.###>
>> Subject: [concurrency-interest] Problem with ReentrantReadWriteLock
>> Date: Thu, 1 Jul 2004 10:01:19 +0100
>>
>> Hi,
>>
>> I'm using an executor service with a fixed thread pool size of 2. Both tasks
>> use a custom-cache to which access is protected with a
>> ReentrantReadWriteLock. If I create the lock with fairness set to false
>> (default), everything works ok. However, if I create the lock with fairness
>> set to true, processing hangs (CPU idle) very quickly as if it is
>> deadlocked. Breaking into the debugger shows the thread details below.
>>
>> It looks to me like:
>>
>> Thread 1 has just entered the cache, and has no locks. It is waiting for the
>> Read lock:
>> rwl.readLock().lock();
>>
>> Thread 2 has just updated the cache. It has the write lock, and is trying to
>> downgrade to a Read lock with:
>> rwl.readLock().lock();
>> rwl.writeLock().unlock();
>>
>> It looks to me like Thread 2 is not able to get the read lock - even though
>> it currently has the write lock.
>>
>> Any ideas? Is there something that I am misunderstanding about the
>> 'fairness' functionality? Something I'm doing wrong, or possible 'feature'?
>>
>> Incidentally, with beta 1 - when it hung, it would spin on 100% CPU. With
>> beta 2 - it hangs but with the CPU idle.
>>
>> Thanks and regards,
>> Jon Rowland
>>
>> pool-1-thread-2@ad6 prio=5, in group "main", status: WAIT
>> park():-1, Unsafe.java
>> park():118, LockSupport.java
>> parkAndCheckInterrupt():681, AbstractQueuedSynchronizer.java
>> doAcquireShared():809, AbstractQueuedSynchronizer.java
>> acquireShared():1124, AbstractQueuedSynchronizer.java
>> lock():421, ReentrantReadWriteLock.java
>> getItem():70, DateCacheKeyOnDemand.java
>> getItem():30, DateCache.java
>> getRoute():30, SwtIdRutMatchStrRouteDateCache.java
>> matchCommon():160, PreMatch.java
>> matchCdrEvent():156, ServiceHelper.java
>> run():259, MatchAndRateTask.java
>> runTask():650, ThreadPoolExecutor.java
>> run():675, ThreadPoolExecutor.java
>> run():595, Thread.java
>>
>> pool-1-thread-1@add prio=5, in group "main", status: WAIT
>> park():-1, Unsafe.java
>> park():118, LockSupport.java
>> parkAndCheckInterrupt():681, AbstractQueuedSynchronizer.java
>> doAcquireShared():809, AbstractQueuedSynchronizer.java
>> acquireShared():1124, AbstractQueuedSynchronizer.java
>> lock():421, ReentrantReadWriteLock.java
>> getItem():153, DateCacheKeyOnDemand.java
>> getItem():30, DateCache.java
>> getRoute():30, SwtIdRutMatchStrRouteDateCache.java
>> matchCommon():160, PreMatch.java
>> matchCdrEvent():156, ServiceHelper.java
>> run():259, MatchAndRateTask.java
>> runTask():650, ThreadPoolExecutor.java
>> run():675, ThreadPoolExecutor.java
>> run():595, Thread.java
>>
>> Signal Dispatcher@ae1 daemon prio=10, in group "system", status: RUNNING
>>
>> Finalizer@ae2 daemon prio=8, in group "system", status: WAIT
>> wait():-1, Object.java
>> remove():116, ReferenceQueue.java
>> remove():132, ReferenceQueue.java
>> run():159, Finalizer.java
>>
>> Reference Handler@ae3 daemon prio=10, in group "system", status: WAIT
>> wait():-1, Object.java
>> wait():474, Object.java
>> run():116, Reference.java
>>
>> main@1 prio=5, in group "main", status: WAIT
>> park():-1, Unsafe.java
>> parkNanos():146, LockSupport.java
>> awaitNanos():1808, AbstractQueuedSynchronizer.java
>> awaitTermination():1024, ThreadPoolExecutor.java
>> processFile():174, MatchAndRateTask.java
>> runTask():118, MatchAndRateTask.java
>> run():59, TestMatchAndRate.java
>> main():26, TestMatchAndRate.java
>>
ReentrantReadWriteLock:
Email excerpts follow:
>Ok this is a major one :(
But easy to fix!
>> " Acquires the shared lock.
Now phrased as variants of...
Acquires the read lock if the write lock is not held by another thread ...
All appropriate occurrences of "the lock" are now qualified with read
or write.
David:
>> Also in newCondition: the two class names should be in code font, I believe.
>> And the @return should say that it never returns normally.
fixed.
>I still don't know exactly how barging may or may not impact the RWL. :(
By strange coincidence, that c-i post bug report discovered the case
where the code doesn't meet the spec. So now it really IS a major
issue! (Well, the fix was obvious, but very embarassing that I had
messed up fairness vs reentrance checks.) Could you review the
change?
Martin: You probably didn't see this mail. Could you put in a
bug report?
>> From: Jon Rowland <###@###.###>
>> Sender: ###@###.###
>> To: ###@###.###
>> Cc: Jon Rowland <###@###.###>
>> Subject: [concurrency-interest] Problem with ReentrantReadWriteLock
>> Date: Thu, 1 Jul 2004 10:01:19 +0100
>>
>> Hi,
>>
>> I'm using an executor service with a fixed thread pool size of 2. Both tasks
>> use a custom-cache to which access is protected with a
>> ReentrantReadWriteLock. If I create the lock with fairness set to false
>> (default), everything works ok. However, if I create the lock with fairness
>> set to true, processing hangs (CPU idle) very quickly as if it is
>> deadlocked. Breaking into the debugger shows the thread details below.
>>
>> It looks to me like:
>>
>> Thread 1 has just entered the cache, and has no locks. It is waiting for the
>> Read lock:
>> rwl.readLock().lock();
>>
>> Thread 2 has just updated the cache. It has the write lock, and is trying to
>> downgrade to a Read lock with:
>> rwl.readLock().lock();
>> rwl.writeLock().unlock();
>>
>> It looks to me like Thread 2 is not able to get the read lock - even though
>> it currently has the write lock.
>>
>> Any ideas? Is there something that I am misunderstanding about the
>> 'fairness' functionality? Something I'm doing wrong, or possible 'feature'?
>>
>> Incidentally, with beta 1 - when it hung, it would spin on 100% CPU. With
>> beta 2 - it hangs but with the CPU idle.
>>
>> Thanks and regards,
>> Jon Rowland
>>
>> pool-1-thread-2@ad6 prio=5, in group "main", status: WAIT
>> park():-1, Unsafe.java
>> park():118, LockSupport.java
>> parkAndCheckInterrupt():681, AbstractQueuedSynchronizer.java
>> doAcquireShared():809, AbstractQueuedSynchronizer.java
>> acquireShared():1124, AbstractQueuedSynchronizer.java
>> lock():421, ReentrantReadWriteLock.java
>> getItem():70, DateCacheKeyOnDemand.java
>> getItem():30, DateCache.java
>> getRoute():30, SwtIdRutMatchStrRouteDateCache.java
>> matchCommon():160, PreMatch.java
>> matchCdrEvent():156, ServiceHelper.java
>> run():259, MatchAndRateTask.java
>> runTask():650, ThreadPoolExecutor.java
>> run():675, ThreadPoolExecutor.java
>> run():595, Thread.java
>>
>> pool-1-thread-1@add prio=5, in group "main", status: WAIT
>> park():-1, Unsafe.java
>> park():118, LockSupport.java
>> parkAndCheckInterrupt():681, AbstractQueuedSynchronizer.java
>> doAcquireShared():809, AbstractQueuedSynchronizer.java
>> acquireShared():1124, AbstractQueuedSynchronizer.java
>> lock():421, ReentrantReadWriteLock.java
>> getItem():153, DateCacheKeyOnDemand.java
>> getItem():30, DateCache.java
>> getRoute():30, SwtIdRutMatchStrRouteDateCache.java
>> matchCommon():160, PreMatch.java
>> matchCdrEvent():156, ServiceHelper.java
>> run():259, MatchAndRateTask.java
>> runTask():650, ThreadPoolExecutor.java
>> run():675, ThreadPoolExecutor.java
>> run():595, Thread.java
>>
>> Signal Dispatcher@ae1 daemon prio=10, in group "system", status: RUNNING
>>
>> Finalizer@ae2 daemon prio=8, in group "system", status: WAIT
>> wait():-1, Object.java
>> remove():116, ReferenceQueue.java
>> remove():132, ReferenceQueue.java
>> run():159, Finalizer.java
>>
>> Reference Handler@ae3 daemon prio=10, in group "system", status: WAIT
>> wait():-1, Object.java
>> wait():474, Object.java
>> run():116, Reference.java
>>
>> main@1 prio=5, in group "main", status: WAIT
>> park():-1, Unsafe.java
>> parkNanos():146, LockSupport.java
>> awaitNanos():1808, AbstractQueuedSynchronizer.java
>> awaitTermination():1024, ThreadPoolExecutor.java
>> processFile():174, MatchAndRateTask.java
>> runTask():118, MatchAndRateTask.java
>> run():59, TestMatchAndRate.java
>> main():26, TestMatchAndRate.java
>>