# HG changeset patch # User dl # Date 1372417818 -3600 # Node ID 2ab0d0b3ecad27a729598a9269abb1d731f15af6 # Parent 53b8b8c30086949bf379c34885ab878f9d5cb1c3 8017739: ReentrantReadWriteLock is confused by the Threads with reused IDs Reviewed-by: chegar diff -r 53b8b8c30086 -r 2ab0d0b3ecad jdk/src/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java --- a/jdk/src/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java Fri Jun 28 10:29:21 2013 +0200 +++ b/jdk/src/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java Fri Jun 28 12:10:18 2013 +0100 @@ -45,7 +45,7 @@ *
This class does not impose a reader or writer preference + *
This class does not impose a reader or writer preference * ordering for lock access. However, it does support an optional * fairness policy. * @@ -59,7 +59,7 @@ *
* *
If the number of readers is now zero then the lock + *
If the number of readers is now zero then the lock * is made available for write lock attempts. */ public void unlock() { @@ -1017,7 +1017,7 @@ * #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) } * which is almost equivalent (it also detects interruption). * - *
If the current thread already holds this lock then the + *
If the current thread already holds this lock then the * hold count is incremented by one and the method returns * {@code true}. * @@ -1126,7 +1126,7 @@ * IllegalMonitorStateException} is thrown. * * @throws IllegalMonitorStateException if the current thread does not - * hold this lock. + * hold this lock */ public void unlock() { sync.release(1); @@ -1254,7 +1254,7 @@ * Queries the number of read locks held for this lock. This * method is designed for use in monitoring system state, not for * synchronization control. - * @return the number of read locks held. + * @return the number of read locks held */ public int getReadLockCount() { return sync.getReadLockCount(); @@ -1484,4 +1484,28 @@ "[Write locks = " + w + ", Read locks = " + r + "]"; } + /** + * Returns the thread id for the given thread. We must access + * this directly rather than via method Thread.getId() because + * getId() is not final, and has been known to be overridden in + * ways that do not preserve unique mappings. + */ + static final long getThreadId(Thread thread) { + return UNSAFE.getLongVolatile(thread, TID_OFFSET); + } + + // Unsafe mechanics + private static final sun.misc.Unsafe UNSAFE; + private static final long TID_OFFSET; + static { + try { + UNSAFE = sun.misc.Unsafe.getUnsafe(); + Class> tk = Thread.class; + TID_OFFSET = UNSAFE.objectFieldOffset + (tk.getDeclaredField("tid")); + } catch (Exception e) { + throw new Error(e); + } + } + }