天天看点

ReentrantLock和synchronized的性能对比

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 &lt; 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 &lt; </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