Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
c7745120
D
dragonwell8_jdk
项目概览
openanolis
/
dragonwell8_jdk
通知
4
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_jdk
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
c7745120
编写于
6月 28, 2013
作者:
D
dl
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8017739: ReentrantReadWriteLock is confused by the Threads with reused IDs
Reviewed-by: chegar
上级
085d2168
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
37 addition
and
13 deletion
+37
-13
src/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java
...es/java/util/concurrent/locks/ReentrantReadWriteLock.java
+37
-13
未找到文件。
src/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java
浏览文件 @
c7745120
...
@@ -45,7 +45,7 @@ import java.util.Collection;
...
@@ -45,7 +45,7 @@ import java.util.Collection;
* <ul>
* <ul>
* <li><b>Acquisition order</b>
* <li><b>Acquisition order</b>
*
*
* <p>
This class does not impose a reader or writer preference
* <p>This class does not impose a reader or writer preference
* ordering for lock access. However, it does support an optional
* ordering for lock access. However, it does support an optional
* <em>fairness</em> policy.
* <em>fairness</em> policy.
*
*
...
@@ -59,7 +59,7 @@ import java.util.Collection;
...
@@ -59,7 +59,7 @@ import java.util.Collection;
* <p>
* <p>
*
*
* <dt><b><i>Fair mode</i></b>
* <dt><b><i>Fair mode</i></b>
* <dd>
When constructed as fair, threads contend for entry using an
* <dd>When constructed as fair, threads contend for entry using an
* approximately arrival-order policy. When the currently held lock
* approximately arrival-order policy. When the currently held lock
* is released, either the longest-waiting single writer thread will
* is released, either the longest-waiting single writer thread will
* be assigned the write lock, or if there is a group of reader threads
* be assigned the write lock, or if there is a group of reader threads
...
@@ -277,7 +277,7 @@ public class ReentrantReadWriteLock
...
@@ -277,7 +277,7 @@ public class ReentrantReadWriteLock
static
final
class
HoldCounter
{
static
final
class
HoldCounter
{
int
count
=
0
;
int
count
=
0
;
// Use id, not reference, to avoid garbage retention
// Use id, not reference, to avoid garbage retention
final
long
tid
=
Thread
.
currentThread
().
getId
(
);
final
long
tid
=
getThreadId
(
Thread
.
currentThread
()
);
}
}
/**
/**
...
@@ -420,7 +420,7 @@ public class ReentrantReadWriteLock
...
@@ -420,7 +420,7 @@ public class ReentrantReadWriteLock
firstReaderHoldCount
--;
firstReaderHoldCount
--;
}
else
{
}
else
{
HoldCounter
rh
=
cachedHoldCounter
;
HoldCounter
rh
=
cachedHoldCounter
;
if
(
rh
==
null
||
rh
.
tid
!=
current
.
getId
(
))
if
(
rh
==
null
||
rh
.
tid
!=
getThreadId
(
current
))
rh
=
readHolds
.
get
();
rh
=
readHolds
.
get
();
int
count
=
rh
.
count
;
int
count
=
rh
.
count
;
if
(
count
<=
1
)
{
if
(
count
<=
1
)
{
...
@@ -478,7 +478,7 @@ public class ReentrantReadWriteLock
...
@@ -478,7 +478,7 @@ public class ReentrantReadWriteLock
firstReaderHoldCount
++;
firstReaderHoldCount
++;
}
else
{
}
else
{
HoldCounter
rh
=
cachedHoldCounter
;
HoldCounter
rh
=
cachedHoldCounter
;
if
(
rh
==
null
||
rh
.
tid
!=
current
.
getId
(
))
if
(
rh
==
null
||
rh
.
tid
!=
getThreadId
(
current
))
cachedHoldCounter
=
rh
=
readHolds
.
get
();
cachedHoldCounter
=
rh
=
readHolds
.
get
();
else
if
(
rh
.
count
==
0
)
else
if
(
rh
.
count
==
0
)
readHolds
.
set
(
rh
);
readHolds
.
set
(
rh
);
...
@@ -515,7 +515,7 @@ public class ReentrantReadWriteLock
...
@@ -515,7 +515,7 @@ public class ReentrantReadWriteLock
}
else
{
}
else
{
if
(
rh
==
null
)
{
if
(
rh
==
null
)
{
rh
=
cachedHoldCounter
;
rh
=
cachedHoldCounter
;
if
(
rh
==
null
||
rh
.
tid
!=
current
.
getId
(
))
{
if
(
rh
==
null
||
rh
.
tid
!=
getThreadId
(
current
))
{
rh
=
readHolds
.
get
();
rh
=
readHolds
.
get
();
if
(
rh
.
count
==
0
)
if
(
rh
.
count
==
0
)
readHolds
.
remove
();
readHolds
.
remove
();
...
@@ -536,7 +536,7 @@ public class ReentrantReadWriteLock
...
@@ -536,7 +536,7 @@ public class ReentrantReadWriteLock
}
else
{
}
else
{
if
(
rh
==
null
)
if
(
rh
==
null
)
rh
=
cachedHoldCounter
;
rh
=
cachedHoldCounter
;
if
(
rh
==
null
||
rh
.
tid
!=
current
.
getId
(
))
if
(
rh
==
null
||
rh
.
tid
!=
getThreadId
(
current
))
rh
=
readHolds
.
get
();
rh
=
readHolds
.
get
();
else
if
(
rh
.
count
==
0
)
else
if
(
rh
.
count
==
0
)
readHolds
.
set
(
rh
);
readHolds
.
set
(
rh
);
...
@@ -592,7 +592,7 @@ public class ReentrantReadWriteLock
...
@@ -592,7 +592,7 @@ public class ReentrantReadWriteLock
firstReaderHoldCount
++;
firstReaderHoldCount
++;
}
else
{
}
else
{
HoldCounter
rh
=
cachedHoldCounter
;
HoldCounter
rh
=
cachedHoldCounter
;
if
(
rh
==
null
||
rh
.
tid
!=
current
.
getId
(
))
if
(
rh
==
null
||
rh
.
tid
!=
getThreadId
(
current
))
cachedHoldCounter
=
rh
=
readHolds
.
get
();
cachedHoldCounter
=
rh
=
readHolds
.
get
();
else
if
(
rh
.
count
==
0
)
else
if
(
rh
.
count
==
0
)
readHolds
.
set
(
rh
);
readHolds
.
set
(
rh
);
...
@@ -643,7 +643,7 @@ public class ReentrantReadWriteLock
...
@@ -643,7 +643,7 @@ public class ReentrantReadWriteLock
return
firstReaderHoldCount
;
return
firstReaderHoldCount
;
HoldCounter
rh
=
cachedHoldCounter
;
HoldCounter
rh
=
cachedHoldCounter
;
if
(
rh
!=
null
&&
rh
.
tid
==
current
.
getId
(
))
if
(
rh
!=
null
&&
rh
.
tid
==
getThreadId
(
current
))
return
rh
.
count
;
return
rh
.
count
;
int
count
=
readHolds
.
get
().
count
;
int
count
=
readHolds
.
get
().
count
;
...
@@ -875,7 +875,7 @@ public class ReentrantReadWriteLock
...
@@ -875,7 +875,7 @@ public class ReentrantReadWriteLock
/**
/**
* Attempts to release this lock.
* Attempts to release this lock.
*
*
* <p>
If the number of readers is now zero then the lock
* <p>If the number of readers is now zero then the lock
* is made available for write lock attempts.
* is made available for write lock attempts.
*/
*/
public
void
unlock
()
{
public
void
unlock
()
{
...
@@ -1017,7 +1017,7 @@ public class ReentrantReadWriteLock
...
@@ -1017,7 +1017,7 @@ public class ReentrantReadWriteLock
* #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) }
* #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) }
* which is almost equivalent (it also detects interruption).
* which is almost equivalent (it also detects interruption).
*
*
* <p>
If the current thread already holds this lock then the
* <p>If the current thread already holds this lock then the
* hold count is incremented by one and the method returns
* hold count is incremented by one and the method returns
* {@code true}.
* {@code true}.
*
*
...
@@ -1126,7 +1126,7 @@ public class ReentrantReadWriteLock
...
@@ -1126,7 +1126,7 @@ public class ReentrantReadWriteLock
* IllegalMonitorStateException} is thrown.
* IllegalMonitorStateException} is thrown.
*
*
* @throws IllegalMonitorStateException if the current thread does not
* @throws IllegalMonitorStateException if the current thread does not
* hold this lock
.
* hold this lock
*/
*/
public
void
unlock
()
{
public
void
unlock
()
{
sync
.
release
(
1
);
sync
.
release
(
1
);
...
@@ -1254,7 +1254,7 @@ public class ReentrantReadWriteLock
...
@@ -1254,7 +1254,7 @@ public class ReentrantReadWriteLock
* Queries the number of read locks held for this lock. This
* Queries the number of read locks held for this lock. This
* method is designed for use in monitoring system state, not for
* method is designed for use in monitoring system state, not for
* synchronization control.
* synchronization control.
* @return the number of read locks held
.
* @return the number of read locks held
*/
*/
public
int
getReadLockCount
()
{
public
int
getReadLockCount
()
{
return
sync
.
getReadLockCount
();
return
sync
.
getReadLockCount
();
...
@@ -1484,4 +1484,28 @@ public class ReentrantReadWriteLock
...
@@ -1484,4 +1484,28 @@ public class ReentrantReadWriteLock
"[Write locks = "
+
w
+
", Read locks = "
+
r
+
"]"
;
"[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
);
}
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录