首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

ReentrantLock跟内部锁的性能对比【转】

2012-11-03 
ReentrantLock和内部锁的性能对比【转】?ReentrantLock是jdk5引入的新的锁机制,它与内部锁(synchronize) 相

ReentrantLock和内部锁的性能对比【转】

?ReentrantLock是jdk5引入的新的锁机制,它与内部锁(synchronize) 相同的并发性和内存语义,比如可重入加锁语义。在中等或者更高负荷下,ReentrantLock有更好的性能,并且拥有可轮询和可定时的请求锁等高级功能。这个程序简单对比了ReentrantLock公平锁、ReentrantLock非公平锁以及内部锁的性能,从结果上看,非公平的ReentrantLock表现最好。内部锁也仅仅是实现统计意义上的公平,结果也比公平的ReentrantLock好上很多。这个程序仅仅是计数,启动N个线程,对同一个Counter进行递增,显然,这个递增操作需要同步以保证原子性,采用不同的锁来实现同步,然后查看结果。
Counter接口:

package?net.rubyeye.concurrency.chapter13;

public?interface?Counter?{
????public?long?getValue();

????public?void?increment();

}


然后,首先使用我们熟悉的synchronize来实现同步:

package?net.rubyeye.concurrency.chapter13;

public?class?SynchronizeBenchmark?implements?Counter?{
????private?long?count?=?0;

????public?long?getValue()?{
????????return?count;
????}

????public?synchronized?void?increment()?{
????????count++;
????}
}


采用ReentrantLock的版本,切记要在finally中释放锁,这是与synchronize使用方式最大的不同,内部锁jvm会自动帮你释放锁,而ReentrantLock需要你自己来处理。

package?net.rubyeye.concurrency.chapter13;

import?java.util.concurrent.locks.Lock;
import?java.util.concurrent.locks.ReentrantLock;

public?class?ReentrantLockBeanchmark?implements?Counter?{

????private?volatile?long?count?=?0;

????private?Lock?lock;

????public?ReentrantLockBeanchmark()?{
????????//?使用非公平锁,true就是公平锁
????????lock?=?new?ReentrantLock(false);
????}

????public?long?getValue()?{
????????//?TODO?Auto-generated?method?stub
????????return?count;
????}

????public?void?increment()?{
????????lock.lock();
????????try?{
????????????count++;
????????}?finally?{
????????????lock.unlock();
????????}
????}

}


??? 写一个测试程序,使用CyclicBarrier来等待所有任务线程创建完毕以及所有任务线程计算完成,清单如下:

package?net.rubyeye.concurrency.chapter13;

import?java.util.concurrent.CyclicBarrier;

public?class?BenchmarkTest?{
????private?Counter?counter;

????private?CyclicBarrier?barrier;

????private?int?threadNum;

????public?BenchmarkTest(Counter?counter,?int?threadNum)?{
????????this.counter?=?counter;
????????barrier?=?new?CyclicBarrier(threadNum?+?1);?//关卡计数=线程数+1
????????this.threadNum?=?threadNum;
????}

????public?static?void?main(String?args[])?{
????????new?BenchmarkTest(new?SynchronizeBenchmark(),?5000).test();
? ? ? ??//new?BenchmarkTest(new?ReentrantLockBeanchmark(),?5000).test();
??????? //new?BenchmarkTest(new?ReentrantLockBeanchmark(),?5000).test();???
????}

????public?void?test()?{
????????try?{
????????????for?(int?i?=?0;?i?<?threadNum;?i++)?{
????????????????new?TestThread(counter).start();
????????????}
??? ? ? ? ??long?start?=?System.currentTimeMillis();
??????????? barrier.await();?//?等待所有任务线程创建
????????????barrier.await();?//?等待所有任务计算完成
????????????long?end?=?System.currentTimeMillis();
????????????System.out.println("count?value:"?+?counter.getValue());
????????????System.out.println("花费时间:"?+?(end?-?start)?+?"毫秒");
????????}?catch?(Exception?e)?{
????????????throw?new?RuntimeException(e);
????????}
????}

????class?TestThread?extends?Thread?{
????????private?Counter?counter;

????????public?TestThread(final?Counter?counter)?{
????????????this.counter?=?counter;
????????}

????????public?void?run()?{
????????????try?{
????????????????barrier.await();
????????????????for?(int?i?=?0;?i?<?100;?i++)
????????????????????counter.increment();
????????????????barrier.await();
????????????}?catch?(Exception?e)?{
????????????????throw?new?RuntimeException(e);
????????????}
????????}
????}
}

?


分别测试一下,

将启动的线程数限定为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的内部锁机制进行了调整

?

热点排行