Redian新闻
>
同一个Lock锁两次,性能比较差
avatar
同一个Lock锁两次,性能比较差# Java - 爪哇娇娃
u*l
1
读别人的代码,发现有一个地方同一个Lock被锁了两次:
调用的Method:
while (.....) {
Reader reader = (Reader) readers.next();
synchronized (reader) {
if (reader.getCount() > 0) {
do sth
}
}
}
Reader 的定义:
public synchronized int getCount() {
return count;
}
可以看到,reader object 被锁了两次。
既然Synchronized block已经锁了reader object, 里面应该可以调用一个非同步的
getCount(). 性能会提高很多。
也就是说,添加一个:
public int getCountRegular() {
return count;
}
这样做值得吗?
avatar
g*g
2
It's a re-entrant lock, this makes no difference.
If you really want to improve performance, try
AtomicInteger as counter may help a little.

【在 u*l 的大作中提到】
: 读别人的代码,发现有一个地方同一个Lock被锁了两次:
: 调用的Method:
: while (.....) {
: Reader reader = (Reader) readers.next();
: synchronized (reader) {
: if (reader.getCount() > 0) {
: do sth
: }
: }
: }

avatar
u*l
3
我试着测试了一下性能差异,发现其实差很多。
只锁一次的话,每秒钟可以Loop 13K;
锁两次,只能Loop 9K。

【在 g*****g 的大作中提到】
: It's a re-entrant lock, this makes no difference.
: If you really want to improve performance, try
: AtomicInteger as counter may help a little.

avatar
g*g
4
When you declare synchronized, it does a check.
there's no additional lock. I doubt you'll notice any difference
if the synchronized block has non-trival code.

【在 u*l 的大作中提到】
: 我试着测试了一下性能差异,发现其实差很多。
: 只锁一次的话,每秒钟可以Loop 13K;
: 锁两次,只能Loop 9K。

avatar
u*l
5
But the checking (when locking and unlocking) takes time.
The code inside the synchronized block is trivial...

【在 g*****g 的大作中提到】
: When you declare synchronized, it does a check.
: there's no additional lock. I doubt you'll notice any difference
: if the synchronized block has non-trival code.

avatar
r*s
6
java5 vs 6在lock上的实现上差别也大
你如果用的是5测的,
用6/7也许差别就不大了

【在 u*l 的大作中提到】
: 我试着测试了一下性能差异,发现其实差很多。
: 只锁一次的话,每秒钟可以Loop 13K;
: 锁两次,只能Loop 9K。

avatar
r*l
7
Create a non-locking read will help. In addition, I suggest that you move
the "sync" keyword inside the "if" statement. Of course you need to do
another read count inside the sync. Unless the hit rate of the "if" is close
to 100%, you should have some performance gain.
After the change, the logic should be very similar to the singleton class
double null check. You need to review your code very carefully to see if
there is similar pitfall. Only if performance is REALLY important to you.

【在 u*l 的大作中提到】
: 读别人的代码,发现有一个地方同一个Lock被锁了两次:
: 调用的Method:
: while (.....) {
: Reader reader = (Reader) readers.next();
: synchronized (reader) {
: if (reader.getCount() > 0) {
: do sth
: }
: }
: }

avatar
u*l
8
Thanks for the reply!
By the way, I am using HotSpot, is JVM doing related optimizations that
remove the overhead of "double-locking". I heard about this from somewhere,
but don't understand it.

close

【在 r*****l 的大作中提到】
: Create a non-locking read will help. In addition, I suggest that you move
: the "sync" keyword inside the "if" statement. Of course you need to do
: another read count inside the sync. Unless the hit rate of the "if" is close
: to 100%, you should have some performance gain.
: After the change, the logic should be very similar to the singleton class
: double null check. You need to review your code very carefully to see if
: there is similar pitfall. Only if performance is REALLY important to you.

avatar
r*l
9
You might want to read the concurrency package from Java 5 and try to
migrate your code. It's way easier to use.

,

【在 u*l 的大作中提到】
: Thanks for the reply!
: By the way, I am using HotSpot, is JVM doing related optimizations that
: remove the overhead of "double-locking". I heard about this from somewhere,
: but don't understand it.
:
: close

avatar
s*e
10
Java 6是会在编译阶段就把一些比较明显的非必要的synchronized去掉的。你可以用
jdk6编译一下看看结果如何

,

【在 u*l 的大作中提到】
: Thanks for the reply!
: By the way, I am using HotSpot, is JVM doing related optimizations that
: remove the overhead of "double-locking". I heard about this from somewhere,
: but don't understand it.
:
: close

avatar
u*l
11
The JDK version I used is 6.25.

【在 s*******e 的大作中提到】
: Java 6是会在编译阶段就把一些比较明显的非必要的synchronized去掉的。你可以用
: jdk6编译一下看看结果如何
:
: ,

avatar
s*e
12
没看看编译过的class?有没有被优化掉?

【在 u*l 的大作中提到】
: The JDK version I used is 6.25.
avatar
s*e
13
If you are working on a nontrivial project and the class will be reused as
APIs, you should not trade the maintainence and simplicity with a small
performance gain like that. Otherwise you will be surprised that how many
time other developers use your nonlocked version in an env that needs a lock
version.
Actually the philosophy in the code you see has its name "defensive
rogramming".
相关阅读
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。