-
Bug
-
Resolution: Fixed
-
P4
-
7u6, 8
-
b98
-
generic
-
generic
-
Verified
Originally described at:
http://cs.oswego.edu/pipermail/concurrency-interest/2013-June/011449.html
RRWL stores the thread ID to count the read-lock holders. If the thread read-locks and dies, but some other thread reuses its ID (perfectly legal under Thread.getId() contract), then RRWL treats that new thread as the old one.
EXAMPLE:
public static void main(String[] args) throws InterruptedException {
final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
final CyclicBarrier barrier = new CyclicBarrier(2);
Thread t1 = new LegalThread(1) {
@Override
public void run() {
try {
lock.readLock().lock();
barrier.await();
//T2a locks
//T2b unlocks
barrier.await();
lock.readLock().unlock();
} catch (Exception e) {
e.printStackTrace();
}
}
};
Thread t2a = new LegalThread(2) {
@Override
public void run() {
try {
//T1 locks
barrier.await();
lock.readLock().lock();
} catch (Exception e) {
e.printStackTrace();
}
}
};
t1.start();
t2a.start();
t2a.join();
Thread t2b = new LegalThread(2) {
@Override
public void run() {
try {
lock.readLock().unlock();
barrier.await();
} catch (Exception e) {
e.printStackTrace();
}
}
};
t2b.start();
}
static class LegalThread extends Thread {
private final int id;
public LegalThread(int id) {
this.id = id;
}
@Override
public long getId() {
return id;
}
}
EXPECTED BEHAVIOR:
IllegalMonitorStateException in t2b.run()
ACTUAL BEHAVIOR:
Everything is "fine".
http://cs.oswego.edu/pipermail/concurrency-interest/2013-June/011449.html
RRWL stores the thread ID to count the read-lock holders. If the thread read-locks and dies, but some other thread reuses its ID (perfectly legal under Thread.getId() contract), then RRWL treats that new thread as the old one.
EXAMPLE:
public static void main(String[] args) throws InterruptedException {
final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
final CyclicBarrier barrier = new CyclicBarrier(2);
Thread t1 = new LegalThread(1) {
@Override
public void run() {
try {
lock.readLock().lock();
barrier.await();
//T2a locks
//T2b unlocks
barrier.await();
lock.readLock().unlock();
} catch (Exception e) {
e.printStackTrace();
}
}
};
Thread t2a = new LegalThread(2) {
@Override
public void run() {
try {
//T1 locks
barrier.await();
lock.readLock().lock();
} catch (Exception e) {
e.printStackTrace();
}
}
};
t1.start();
t2a.start();
t2a.join();
Thread t2b = new LegalThread(2) {
@Override
public void run() {
try {
lock.readLock().unlock();
barrier.await();
} catch (Exception e) {
e.printStackTrace();
}
}
};
t2b.start();
}
static class LegalThread extends Thread {
private final int id;
public LegalThread(int id) {
this.id = id;
}
@Override
public long getId() {
return id;
}
}
EXPECTED BEHAVIOR:
IllegalMonitorStateException in t2b.run()
ACTUAL BEHAVIOR:
Everything is "fine".
- relates to
-
JDK-8017617 (thread) Deprecate and provide alternative to Thread.getId()
- Closed