Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
ae3501c3
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看板
提交
ae3501c3
编写于
3月 26, 2009
作者:
D
dl
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
6822903: Reliability and documentation improvements for ReentrantReadWriteLock
Summary: Make firstReader a Thread, not a long Reviewed-by: martin
上级
8d3882c0
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
49 addition
and
37 deletion
+49
-37
src/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java
...es/java/util/concurrent/locks/ReentrantReadWriteLock.java
+49
-37
未找到文件。
src/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java
浏览文件 @
ae3501c3
...
@@ -276,7 +276,7 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab
...
@@ -276,7 +276,7 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab
* Maintained as a ThreadLocal; cached in cachedHoldCounter
* Maintained as a ThreadLocal; cached in cachedHoldCounter
*/
*/
static
final
class
HoldCounter
{
static
final
class
HoldCounter
{
int
count
;
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
=
Thread
.
currentThread
().
getId
();
}
}
...
@@ -293,8 +293,9 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab
...
@@ -293,8 +293,9 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab
}
}
/**
/**
* The number of read locks held by current thread.
* The number of re
entrant re
ad locks held by current thread.
* Initialized only in constructor and readObject.
* Initialized only in constructor and readObject.
* Removed whenever a thread's read hold count drops to 0.
*/
*/
private
transient
ThreadLocalHoldCounter
readHolds
;
private
transient
ThreadLocalHoldCounter
readHolds
;
...
@@ -304,17 +305,35 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab
...
@@ -304,17 +305,35 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab
* where the next thread to release is the last one to
* where the next thread to release is the last one to
* acquire. This is non-volatile since it is just used
* acquire. This is non-volatile since it is just used
* as a heuristic, and would be great for threads to cache.
* as a heuristic, and would be great for threads to cache.
*
* <p>Can outlive the Thread for which it is caching the read
* hold count, but avoids garbage retention by not retaining a
* reference to the Thread.
*
* <p>Accessed via a benign data race; relies on the memory
* model's final field and out-of-thin-air guarantees.
*/
*/
private
transient
HoldCounter
cachedHoldCounter
;
private
transient
HoldCounter
cachedHoldCounter
;
/**
/**
* firstReader is the first thread to have acquired the read lock.
* firstReader is the first thread to have acquired the read lock.
* firstReaderHoldCount is firstReader's hold count.
* firstReaderHoldCount is firstReader's hold count.
* This allows tracking of read holds for uncontended read
*
* <p>More precisely, firstReader is the unique thread that last
* changed the shared count from 0 to 1, and has not released the
* read lock since then; null if there is no such thread.
*
* <p>Cannot cause garbage retention unless the thread terminated
* without relinquishing its read locks, since tryReleaseShared
* sets it to null.
*
* <p>Accessed via a benign data race; relies on the memory
* model's out-of-thin-air guarantees for references.
*
* <p>This allows tracking of read holds for uncontended read
* locks to be very cheap.
* locks to be very cheap.
*/
*/
private
final
static
long
INVALID_THREAD_ID
=
-
1
;
private
transient
Thread
firstReader
=
null
;
private
transient
long
firstReader
=
INVALID_THREAD_ID
;
private
transient
int
firstReaderHoldCount
;
private
transient
int
firstReaderHoldCount
;
Sync
()
{
Sync
()
{
...
@@ -393,16 +412,16 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab
...
@@ -393,16 +412,16 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab
}
}
protected
final
boolean
tryReleaseShared
(
int
unused
)
{
protected
final
boolean
tryReleaseShared
(
int
unused
)
{
long
tid
=
Thread
.
currentThread
().
getI
d
();
Thread
current
=
Thread
.
currentThrea
d
();
if
(
firstReader
==
tid
)
{
if
(
firstReader
==
current
)
{
// assert firstReaderHoldCount > 0;
// assert firstReaderHoldCount > 0;
if
(
firstReaderHoldCount
==
1
)
if
(
firstReaderHoldCount
==
1
)
firstReader
=
INVALID_THREAD_ID
;
firstReader
=
null
;
else
else
firstReaderHoldCount
--;
firstReaderHoldCount
--;
}
else
{
}
else
{
HoldCounter
rh
=
cachedHoldCounter
;
HoldCounter
rh
=
cachedHoldCounter
;
if
(
rh
==
null
||
rh
.
tid
!=
tid
)
if
(
rh
==
null
||
rh
.
tid
!=
current
.
getId
()
)
rh
=
readHolds
.
get
();
rh
=
readHolds
.
get
();
int
count
=
rh
.
count
;
int
count
=
rh
.
count
;
if
(
count
<=
1
)
{
if
(
count
<=
1
)
{
...
@@ -416,6 +435,9 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab
...
@@ -416,6 +435,9 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab
int
c
=
getState
();
int
c
=
getState
();
int
nextc
=
c
-
SHARED_UNIT
;
int
nextc
=
c
-
SHARED_UNIT
;
if
(
compareAndSetState
(
c
,
nextc
))
if
(
compareAndSetState
(
c
,
nextc
))
// Releasing the read lock has no effect on readers,
// but it may allow waiting writers to proceed if
// both read and write locks are now free.
return
nextc
==
0
;
return
nextc
==
0
;
}
}
}
}
...
@@ -450,15 +472,14 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab
...
@@ -450,15 +472,14 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab
if
(!
readerShouldBlock
()
&&
if
(!
readerShouldBlock
()
&&
r
<
MAX_COUNT
&&
r
<
MAX_COUNT
&&
compareAndSetState
(
c
,
c
+
SHARED_UNIT
))
{
compareAndSetState
(
c
,
c
+
SHARED_UNIT
))
{
long
tid
=
current
.
getId
();
if
(
r
==
0
)
{
if
(
r
==
0
)
{
firstReader
=
tid
;
firstReader
=
current
;
firstReaderHoldCount
=
1
;
firstReaderHoldCount
=
1
;
}
else
if
(
firstReader
==
tid
)
{
}
else
if
(
firstReader
==
current
)
{
firstReaderHoldCount
++;
firstReaderHoldCount
++;
}
else
{
}
else
{
HoldCounter
rh
=
cachedHoldCounter
;
HoldCounter
rh
=
cachedHoldCounter
;
if
(
rh
==
null
||
rh
.
tid
!=
tid
)
if
(
rh
==
null
||
rh
.
tid
!=
current
.
getId
()
)
cachedHoldCounter
=
rh
=
readHolds
.
get
();
cachedHoldCounter
=
rh
=
readHolds
.
get
();
else
if
(
rh
.
count
==
0
)
else
if
(
rh
.
count
==
0
)
readHolds
.
set
(
rh
);
readHolds
.
set
(
rh
);
...
@@ -485,19 +506,17 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab
...
@@ -485,19 +506,17 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab
int
c
=
getState
();
int
c
=
getState
();
if
(
exclusiveCount
(
c
)
!=
0
)
{
if
(
exclusiveCount
(
c
)
!=
0
)
{
if
(
getExclusiveOwnerThread
()
!=
current
)
if
(
getExclusiveOwnerThread
()
!=
current
)
//if (removeNeeded) readHolds.remove();
return
-
1
;
return
-
1
;
// else we hold the exclusive lock; blocking here
// else we hold the exclusive lock; blocking here
// would cause deadlock.
// would cause deadlock.
}
else
if
(
readerShouldBlock
())
{
}
else
if
(
readerShouldBlock
())
{
// Make sure we're not acquiring read lock reentrantly
// Make sure we're not acquiring read lock reentrantly
long
tid
=
current
.
getId
();
if
(
firstReader
==
current
)
{
if
(
firstReader
==
tid
)
{
// assert firstReaderHoldCount > 0;
// assert firstReaderHoldCount > 0;
}
else
{
}
else
{
if
(
rh
==
null
)
{
if
(
rh
==
null
)
{
rh
=
cachedHoldCounter
;
rh
=
cachedHoldCounter
;
if
(
rh
==
null
||
rh
.
tid
!=
tid
)
{
if
(
rh
==
null
||
rh
.
tid
!=
current
.
getId
()
)
{
rh
=
readHolds
.
get
();
rh
=
readHolds
.
get
();
if
(
rh
.
count
==
0
)
if
(
rh
.
count
==
0
)
readHolds
.
remove
();
readHolds
.
remove
();
...
@@ -510,25 +529,20 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab
...
@@ -510,25 +529,20 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab
if
(
sharedCount
(
c
)
==
MAX_COUNT
)
if
(
sharedCount
(
c
)
==
MAX_COUNT
)
throw
new
Error
(
"Maximum lock count exceeded"
);
throw
new
Error
(
"Maximum lock count exceeded"
);
if
(
compareAndSetState
(
c
,
c
+
SHARED_UNIT
))
{
if
(
compareAndSetState
(
c
,
c
+
SHARED_UNIT
))
{
long
tid
=
current
.
getId
();
if
(
sharedCount
(
c
)
==
0
)
{
if
(
sharedCount
(
c
)
==
0
)
{
firstReader
=
tid
;
firstReader
=
current
;
firstReaderHoldCount
=
1
;
firstReaderHoldCount
=
1
;
}
else
if
(
firstReader
==
tid
)
{
}
else
if
(
firstReader
==
current
)
{
firstReaderHoldCount
++;
firstReaderHoldCount
++;
}
else
{
}
else
{
if
(
rh
==
null
)
{
if
(
rh
==
null
)
rh
=
cachedHoldCounter
;
rh
=
cachedHoldCounter
;
if
(
rh
!=
null
&&
rh
.
tid
==
tid
)
{
if
(
rh
==
null
||
rh
.
tid
!=
current
.
getId
())
if
(
rh
.
count
==
0
)
rh
=
readHolds
.
get
();
readHolds
.
set
(
rh
);
else
if
(
rh
.
count
==
0
)
}
else
{
rh
=
readHolds
.
get
();
}
}
else
if
(
rh
.
count
==
0
)
readHolds
.
set
(
rh
);
readHolds
.
set
(
rh
);
cachedHoldCounter
=
rh
;
// cache for release
rh
.
count
++;
rh
.
count
++;
cachedHoldCounter
=
rh
;
// cache for release
}
}
return
1
;
return
1
;
}
}
...
@@ -572,15 +586,14 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab
...
@@ -572,15 +586,14 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab
if
(
r
==
MAX_COUNT
)
if
(
r
==
MAX_COUNT
)
throw
new
Error
(
"Maximum lock count exceeded"
);
throw
new
Error
(
"Maximum lock count exceeded"
);
if
(
compareAndSetState
(
c
,
c
+
SHARED_UNIT
))
{
if
(
compareAndSetState
(
c
,
c
+
SHARED_UNIT
))
{
long
tid
=
current
.
getId
();
if
(
r
==
0
)
{
if
(
r
==
0
)
{
firstReader
=
tid
;
firstReader
=
current
;
firstReaderHoldCount
=
1
;
firstReaderHoldCount
=
1
;
}
else
if
(
firstReader
==
tid
)
{
}
else
if
(
firstReader
==
current
)
{
firstReaderHoldCount
++;
firstReaderHoldCount
++;
}
else
{
}
else
{
HoldCounter
rh
=
cachedHoldCounter
;
HoldCounter
rh
=
cachedHoldCounter
;
if
(
rh
==
null
||
rh
.
tid
!=
tid
)
if
(
rh
==
null
||
rh
.
tid
!=
current
.
getId
()
)
cachedHoldCounter
=
rh
=
readHolds
.
get
();
cachedHoldCounter
=
rh
=
readHolds
.
get
();
else
if
(
rh
.
count
==
0
)
else
if
(
rh
.
count
==
0
)
readHolds
.
set
(
rh
);
readHolds
.
set
(
rh
);
...
@@ -626,12 +639,12 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab
...
@@ -626,12 +639,12 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab
if
(
getReadLockCount
()
==
0
)
if
(
getReadLockCount
()
==
0
)
return
0
;
return
0
;
long
tid
=
Thread
.
currentThread
().
getI
d
();
Thread
current
=
Thread
.
currentThrea
d
();
if
(
firstReader
==
tid
)
if
(
firstReader
==
current
)
return
firstReaderHoldCount
;
return
firstReaderHoldCount
;
HoldCounter
rh
=
cachedHoldCounter
;
HoldCounter
rh
=
cachedHoldCounter
;
if
(
rh
!=
null
&&
rh
.
tid
==
tid
)
if
(
rh
!=
null
&&
rh
.
tid
==
current
.
getId
()
)
return
rh
.
count
;
return
rh
.
count
;
int
count
=
readHolds
.
get
().
count
;
int
count
=
readHolds
.
get
().
count
;
...
@@ -647,7 +660,6 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab
...
@@ -647,7 +660,6 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab
throws
java
.
io
.
IOException
,
ClassNotFoundException
{
throws
java
.
io
.
IOException
,
ClassNotFoundException
{
s
.
defaultReadObject
();
s
.
defaultReadObject
();
readHolds
=
new
ThreadLocalHoldCounter
();
readHolds
=
new
ThreadLocalHoldCounter
();
firstReader
=
INVALID_THREAD_ID
;
setState
(
0
);
// reset to unlocked state
setState
(
0
);
// reset to unlocked state
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录