FULL PRODUCT VERSION :
java version "1.6.0_26"
Java(TM) SE Runtime Environment (build 1.6.0_26-b03)
Java HotSpot(TM) Client VM (build 20.1-b02, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7600]
A DESCRIPTION OF THE PROBLEM :
The following code:
ReentrantReadWriteLock rwl=new ReentrantReadWriteLock();
final Lock l=rwl.readLock();
Thread t=new Thread(new Runnable() {
public void run() {
l.lock();
}
});
t.start();
while (t.isAlive()){
try {
Thread.sleep(100);
} catch (InterruptedException ie){
// noop
}
}
l.unlock();
Works on Java 1.5, fails on Java 1.6 on the unlock() call with a IllegalStateMonitorException.
The javadoc for Lock.unlock states:
A Lock implementation will usually impose restrictions on which thread can release a lock (typically only the holder of the lock can release it) and may throw an (unchecked) exception if the restriction is violated. Any restrictions and the exception type must be documented by that Lock implementation.
The javadoc for ReentrantReadWriteLock.ReadLock.unlock states:
Attempts to release this lock.
If the number of readers is now zero then the lock is made available for write lock attempts.
Hence, there shouldn't be the limitation that only the thread that took the read lock can unlock it. Since it works in Java 1.5 and I can see in the source the implementation has changed, either it's a code bug or the documentation should be updated.
REGRESSION. Last worked in version 5.0
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
ReentrantReadWriteLock rwl=new ReentrantReadWriteLock();
final Lock l=rwl.readLock();
Thread t=new Thread(new Runnable() {
public void run() {
l.lock();
}
});
t.start();
while (t.isAlive()){
try {
Thread.sleep(100);
} catch (InterruptedException ie){
// noop
}
}
l.unlock();
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
No error!!
ACTUAL -
IllegalStateMonitorException at java.util.concurrent.locks.ReentrantReadWriteLock$Sync.tryReleaseShared(ReentrantReadWriteLock.java:363)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.releaseShared(AbstractQueuedSynchronizer.java:1317)
at java.util.concurrent.locks.ReentrantReadWriteLock$ReadLock.unlock(ReentrantReadWriteLock.java:745)
ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "main" java.lang.IllegalMonitorStateException
at java.util.concurrent.locks.ReentrantReadWriteLock$Sync.tryReleaseShared(ReentrantReadWriteLock.java:363)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.releaseShared(AbstractQueuedSynchronizer.java:1317)
at java.util.concurrent.locks.ReentrantReadWriteLock$ReadLock.unlock(ReentrantReadWriteLock.java:745)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class RRWLTest {
/**
* @param args
*/
public static void main(String[] args) {
ReentrantReadWriteLock rwl=new ReentrantReadWriteLock();
final Lock l=rwl.readLock();
Thread t=new Thread(new Runnable() {
public void run() {
l.lock();
}
});
t.start();
while (t.isAlive()){
try {
Thread.sleep(100);
} catch (InterruptedException ie){
// noop
}
}
l.unlock();
}
}
---------- END SOURCE ----------