reentrantlock和内部锁的性能对比
reentrantlock是jdk5引入的新的锁机制,它与内部锁(synchronize) 相同的并发性和内存语义,比如可重入加锁语义。在中等或者更高负荷下,reentrantlock有更好的性能,并且拥有可轮询和可定时的请求锁等高级功能。这个程序简单对比了reentrantlock公平锁、reentrantlock非公平锁以及内部锁的性能,从结果上看,非公平的reentrantlock表现最好。内部锁也仅仅是实现统计意义上的公平,结果也比公平的reentrantlock好上很多。这个程序仅仅是计数,启动n个线程,对同一个counter进行递增,显然,这个递增操作需要同步以保证原子性,采用不同的锁来实现同步,然后查看结果。
counter接口:
1
2
3
4
5
<code>package</code> <code>net.rubyeye.concurrency.chapter13; </code>
<code>public</code> <code>interface</code> <code>counter { </code>
<code> </code><code>public</code> <code>long</code> <code>getvalue(); </code>
<code> </code><code>public</code> <code>void</code> <code>increment(); </code>
<code>}</code>
然后,首先使用我们熟悉的synchronize来实现同步:
6
7
8
9
10
<code>public</code> <code>class</code> <code>synchronizebenchmark </code><code>implements</code> <code>counter { </code>
<code> </code><code>private</code> <code>long</code> <code>count = </code><code>0</code><code>; </code>
<code> </code><code>public</code> <code>long</code> <code>getvalue() { </code>
<code> </code><code>return</code> <code>count; </code>
<code> </code><code>} </code>
<code> </code><code>public</code> <code>synchronized</code> <code>void</code> <code>increment() { </code>
<code> </code><code>count++; </code>
采用reentrantlock的版本,切记要在finally中释放锁,这是与synchronize使用方式最大的不同,内部锁jvm会自动帮你释放锁,而reentrantlock需要你自己来处理。
11
12
13
14
15
16
17
18
19
20
21
22
23
<code>import</code> <code>java.util.concurrent.locks.lock; </code>
<code>import</code> <code>java.util.concurrent.locks.reentrantlock; </code>
<code>public</code> <code>class</code> <code>reentrantlockbeanchmark </code><code>implements</code> <code>counter { </code>
<code> </code><code>private</code> <code>volatile</code> <code>long</code> <code>count = </code><code>0</code><code>; </code>
<code> </code><code>private</code> <code>lock lock; </code>
<code> </code><code>public</code> <code>reentrantlockbeanchmark() { </code>
<code> </code><code>// 使用非公平锁,true就是公平锁 </code>
<code> </code><code>lock = </code><code>new</code> <code>reentrantlock(</code><code>false</code><code>); </code>
<code> </code><code>// todo auto-generated method stub </code>
<code> </code><code>public</code> <code>void</code> <code>increment() { </code>
<code> </code><code>lock.lock(); </code>
<code> </code><code>try</code> <code>{ </code>
<code> </code><code>count++; </code>
<code> </code><code>} </code><code>finally</code> <code>{ </code>
<code> </code><code>lock.unlock(); </code>
<code> </code><code>} </code>
写一个测试程序,使用cyclicbarrier来等待所有任务线程创建完毕以及所有任务线程计算完成,清单如下:
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<code>import</code> <code>java.util.concurrent.cyclicbarrier; </code>
<code>public</code> <code>class</code> <code>benchmarktest { </code>
<code> </code><code>private</code> <code>counter counter; </code>
<code> </code><code>private</code> <code>cyclicbarrier barrier; </code>
<code> </code><code>private</code> <code>int</code> <code>threadnum; </code>
<code> </code><code>public</code> <code>benchmarktest(counter counter, </code><code>int</code> <code>threadnum) { </code>
<code> </code><code>this</code><code>.counter = counter; </code>
<code> </code><code>barrier = </code><code>new</code> <code>cyclicbarrier(threadnum + </code><code>1</code><code>); </code><code>//关卡计数=线程数+1 </code>
<code> </code><code>this</code><code>.threadnum = threadnum; </code>
<code> </code><code>public</code> <code>static</code> <code>void</code> <code>main(string args[]) { </code>
<code> </code><code>new</code> <code>benchmarktest(</code><code>new</code> <code>synchronizebenchmark(), </code><code>5000</code><code>).test(); </code>
<code> </code><code>//new benchmarktest(new reentrantlockbeanchmark(), 5000).test(); </code>
<code> </code><code>//new benchmarktest(new reentrantlockbeanchmark(), 5000).test(); </code>
<code> </code><code>public</code> <code>void</code> <code>test() { </code>
<code> </code><code>for</code> <code>(</code><code>int</code> <code>i = </code><code>0</code><code>; i < threadnum; i++) { </code>
<code> </code><code>new</code> <code>testthread(counter).start(); </code>
<code> </code><code>} </code>
<code> </code><code>long</code> <code>start = system.currenttimemillis(); </code>
<code> </code><code>barrier.await(); </code><code>// 等待所有任务线程创建 </code>
<code> </code><code>barrier.await(); </code><code>// 等待所有任务计算完成 </code>
<code> </code><code>long</code> <code>end = system.currenttimemillis(); </code>
<code> </code><code>system.out.println(</code><code>"count value:"</code> <code>+ counter.getvalue()); </code>
<code> </code><code>system.out.println(</code><code>"花费时间:"</code> <code>+ (end - start) + </code><code>"毫秒"</code><code>); </code>
<code> </code><code>} </code><code>catch</code> <code>(exception e) { </code>
<code> </code><code>throw</code> <code>new</code> <code>runtimeexception(e); </code>
<code> </code><code>class</code> <code>testthread </code><code>extends</code> <code>thread { </code>
<code> </code><code>private</code> <code>counter counter; </code>
<code> </code><code>public</code> <code>testthread(</code><code>final</code> <code>counter counter) { </code>
<code> </code><code>this</code><code>.counter = counter; </code>
<code> </code><code>public</code> <code>void</code> <code>run() { </code>
<code> </code><code>try</code> <code>{ </code>
<code> </code><code>barrier.await(); </code>
<code> </code><code>for</code> <code>(</code><code>int</code> <code>i = </code><code>0</code><code>; i < </code><code>100</code><code>; i++) </code>
<code> </code><code>counter.increment(); </code>
<code> </code><code>} </code><code>catch</code> <code>(exception e) { </code>
<code> </code><code>throw</code> <code>new</code> <code>runtimeexception(e); </code>
分别测试一下,
将启动的线程数限定为500,结果为:
公平reentrantlock: 210 毫秒
非公平reentrantlock : 39 毫秒
内部锁: 39 毫秒
将启动的线程数限定为1000,结果为:
公平reentrantlock: 640 毫秒
非公平reentrantlock : 81 毫秒
内部锁: 60 毫秒
线程数不变,test方法中的循环增加到1000次,结果为:
公平reentrantlock: 16715 毫秒
非公平reentrantlock : 168 毫秒
内部锁: 639 毫秒
将启动的线程数增加到2000,结果为:
公平reentrantlock: 1100 毫秒
非公平reentrantlock: 125 毫秒
内部锁: 130 毫秒
将启动的线程数增加到3000,结果为:
公平reentrantlock: 2461 毫秒
非公平reentrantlock: 254 毫秒
内部锁: 307 毫秒
启动5000个线程,结果如下:
公平reentrantlock: 6154 毫秒
非公平reentrantlock: 623 毫秒
内部锁: 720 毫秒
非公平reentrantlock和内部锁的差距,在jdk6上应该缩小了,据说jdk6的内部锁机制进行了调整。
特别说明:尊重作者的劳动成果,转载请注明出处哦~~~http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytpo8