LockSynchoronized和ReentrantLock的使用.docx

上传人:b****2 文档编号:12873139 上传时间:2023-04-22 格式:DOCX 页数:16 大小:18.72KB
下载 相关 举报
LockSynchoronized和ReentrantLock的使用.docx_第1页
第1页 / 共16页
LockSynchoronized和ReentrantLock的使用.docx_第2页
第2页 / 共16页
LockSynchoronized和ReentrantLock的使用.docx_第3页
第3页 / 共16页
LockSynchoronized和ReentrantLock的使用.docx_第4页
第4页 / 共16页
LockSynchoronized和ReentrantLock的使用.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

LockSynchoronized和ReentrantLock的使用.docx

《LockSynchoronized和ReentrantLock的使用.docx》由会员分享,可在线阅读,更多相关《LockSynchoronized和ReentrantLock的使用.docx(16页珍藏版)》请在冰豆网上搜索。

LockSynchoronized和ReentrantLock的使用.docx

LockSynchoronized和ReentrantLock的使用

比较ReentrantLock和synchronized和信号量Semaphore实现的同步性能

得出结论:

(1)使用Lock的性能比使用synchronized关键字要提高4~5倍;

(2)使用信号量实现同步的速度大约比synchronized要慢10~20%;

(3)使用atomic包的AtomicInter速度是比Lock要快1一个数量级。

synchronized:

在资源竞争不是很激烈的情况下,偶尔会有同步的情形下,synchronized是很合适的。

原因在于,编译程序通常会尽可能的进行优化synchronize,另外可读性非常好,不管用没用过5.0多线程包的程序员都能理解。

ReentrantLock:

ReentrantLock提供了多样化的同步,比如有时间限制的同步,可以被Interrupt的同步(synchronized的同步是不能Interrupt的)等。

在资源竞争不激烈的情形下,性能稍微比synchronized差点点。

但是当同步非常激烈的时候,synchronized的性能一下子能下降好几十倍。

而ReentrantLock确还能维持常态。

Atomic:

和上面的类似,不激烈情况下,性能比synchronized略逊,而激烈的时候,也能维持常态。

激烈的时候,Atomic的性能会优于ReentrantLock一倍左右。

但是其有一个缺点,就是只能同步一个值,一段代码中只能出现一个Atomic的变量,多于一个同步无效。

因为他不能在多个Atomic之间同步。

ReentrantLock类

java.util.concurrent.lock中的Lock框架是锁定的一个抽象,它允许把锁定的实现作为Java类,而不是作为语言的特性来实现。

这就为Lock的多种实现留下了空间,各种实现可能有不同的调度算法、性能特性或者锁定语义。

ReentrantLock类实现了Lock,它拥有与synchronized相同的并发性和内存语义,但是添加了类似锁投票、定时锁等候和可中断锁等候的一些特性。

此外,它还提供了在激烈争用情况下更佳的性能。

(换句话说,当许多线程都想访问共享资源时,JVM可以花更少的时候来调度线程,把更多时间用在执行线程上。

reentrant锁意味着什么呢?

简单来说,它有一个与锁相关的获取计数器,如果拥有锁的某个线程再次得到锁,那么获取计数器就加1,然后锁需要被释放两次才能获得真正释放。

这模仿了synchronized的语义;如果线程进入由线程已经拥有的监控器保护的synchronized块,就允许线程继续进行,当线程退出第二个(或者后续)synchronized块的时候,不释放锁,只有线程退出它进入的监控器保护的第一个synchronized块时,才释放锁。

在查看清单1中的代码示例时,可以看到Lock和synchronized有一点明显的区别——lock必须在finally块中释放。

否则,如果受保护的代码将抛出异常,锁就有可能永远得不到释放!

这一点区别看起来可能没什么,但是实际上,它极为重要。

忘记在finally块中释放锁,可能会在程序中留下一个定时bomb,当有一天bomb爆炸时,您要花费很大力气才有找到源头在哪。

而使用同步,JVM将确保锁会获得自动释放。

publicabstractclassTest{

protectedStringid;

protectedCyclicBarrierbarrier;

protectedlongcount;

protectedintthreadNum;

protectedExecutorServiceexecutor;

publicTest(Stringid,CyclicBarrierbarrier,longcount,intthreadNum,

ExecutorServiceexecutor){

this.id=id;

this.barrier=barrier;

this.count=count;

this.threadNum=threadNum;

this.executor=executor;

}

publicvoidstartTest(){

longstart=System.currentTimeMillis();

for(intj=0;j

executor.execute(newThread(){

@Override

publicvoidrun(){

for(inti=0;i

test();

}

try{

barrier.await();

}catch(InterruptedExceptione){

e.printStackTrace();

}catch(BrokenBarrierExceptione){

e.printStackTrace();

}

}

});

}

try{

barrier.await();

}catch(InterruptedExceptione){

e.printStackTrace();

}catch(BrokenBarrierExceptione){

e.printStackTrace();

}

//所有线程执行完成之后,才会跑到这一步

longduration=System.currentTimeMillis()-start;

System.out.println(id+"="+duration);

}

protectedabstractvoidtest();

}

测试类ReentreLockTest源码

importthread.test.Test;

publicclassReentreLockTest{

privatestaticlongCOUNT=1000000;

privatestaticLocklock=newReentrantLock();

privatestaticlonglockCounter=0;

privatestaticlongsyncCounter=0;

privatestaticlongsemaCounter=0;

privatestaticAtomicLongatomicCounter=newAtomicLong(0);

privatestaticObjectsyncLock=newObject();

privatestaticSemaphoremutex=newSemaphore

(1);

publicstaticvoidtestLock(intnum,intthreadCount){

}

staticlonggetLock(){

lock.lock();

try{

returnlockCounter;

}finally{

lock.unlock();

}

}

staticlonggetSync(){

synchronized(syncLock){

returnsyncCounter;

}

}

staticlonggetAtom(){

returnatomicCounter.get();

}

staticlonggetSemaphore()throwsInterruptedException{

mutex.acquire();

try{

returnsemaCounter;

}finally{

mutex.release();

}

}

staticlonggetLockInc(){

lock.lock();

try{

return++lockCounter;

}finally{

lock.unlock();

}

}

staticlonggetSyncInc(){

synchronized(syncLock){

return++syncCounter;

}

}

staticlonggetAtomInc(){

returnatomicCounter.getAndIncrement();

}

staticclassSemaTestextendsTest{

publicSemaTest(Stringid,CyclicBarrierbarrier,longcount,

intthreadNum,ExecutorServiceexecutor){

super(id,barrier,count,threadNum,executor);

}

@Override

protectedvoidtest(){

try{

getSemaphore();

}catch(InterruptedExceptione){

e.printStackTrace();

}

}

}

staticclassLockTestextendsTest{

publicLockTest(Stringid,CyclicBarrierbarrier,longcount,

intthreadNum,ExecutorServiceexecutor){

super(id,barrier,count,threadNum,executor);

}

@Override

protectedvoidtest(){

getLock();

}

}

staticclassSyncTestextendsTest{

publicSyncTest(Stringid,CyclicBarrierbarrier,longcount,

intthreadNum,ExecutorServiceexecutor){

super(id,barrier,count,threadNum,executor);

}

@Override

protectedvoidtest(){

getSync();

}

}

staticclassAtomicTestextendsTest{

publicAtomicTest(Stringid,CyclicBarrierbarrier,longcount,

intthreadNum,ExecutorServiceexecutor){

super(id,barrier,count,threadNum,executor);

}

@Override

protectedvoidtest(){

getAtom();

}

}

publicstaticvoidtest(Stringid,longcount,intthreadNum,

ExecutorServiceexecutor){

finalCyclicBarrierbarrier=newCyclicBarrier(threadNum+1,

newThread(){

@Override

publicvoidrun(){

}

});

System.out.println("==============================");

System.out.println("count="+count+"/t"+"ThreadCount="

+threadNum);

newLockTest("Lock",barrier,COUNT,threadNum,executor).startTest();

newSyncTest("Sync",barrier,COUNT,threadNum,executor).startTest();

newAtomicTest("Atom",barrier,COUNT,threadNum,executor)

.startTest();

newSemaTest("Sema",barrier,COUNT,threadNum,executor)

.startTest();

System.out.println("==============================");

}

publicstaticvoidmain(String[]args){

for(inti=1;i<5;i++){

ExecutorServiceexecutor=Executors.newFixedThreadPool(10*i);

test("",COUNT*i,10*i,executor);

}

}

}

结果

==============================

count=1000000ThreadCount=10

Lock=953

Sync=3781

Atom=78

Sema=4922

==============================

==============================

count=2000000ThreadCount=20

Lock=1906

Sync=8469

Atom=172

Sema=9719

==============================

==============================

count=3000000ThreadCount=30

Lock=2890

Sync=12641

Atom=219

Sema=15015

==============================

==============================

count=4000000ThreadCount=40

Lock=3844

Sync=17141

Atom=343

Sema=19782

 

packagetest.thread;

importstaticjava.lang.System.out;

importjava.util.Random;

importjava.util.concurrent.BrokenBarrierException;

importjava.util.concurrent.CyclicBarrier;

importjava.util.concurrent.ExecutorService;

importjava.util.concurrent.Executors;

importjava.util.concurrent.atomic.AtomicInteger;

importjava.util.concurrent.atomic.AtomicLong;

importjava.util.concurrent.locks.ReentrantLock;

publicclassTestSyncMethods{

publicstaticvoidtest(intround,intthreadNum,CyclicBarriercyclicBarrier){

newSyncTest("Sync",round,threadNum,cyclicBarrier).testTime();

newLockTest("Lock",round,threadNum,cyclicBarrier).testTime();

newAtomicTest("Atom",round,threadNum,cyclicBarrier).testTime();

}

publicstaticvoidmain(Stringargs[]){

for(inti=0;i<5;i++){

intround=100000*(i+1);

intthreadNum=5*(i+1);

CyclicBarriercb=newCyclicBarrier(threadNum*2+1);

out.println("==========================");

out.println("round:

"+round+"thread:

"+threadNum);

test(round,threadNum,cb);

}

}

}

classSyncTestextendsTestTemplate{

publicSyncTest(String_id,int_round,int_threadNum,CyclicBarrier_cb){

super(_id,_round,_threadNum,_cb);

}

@Override

/**

*synchronized关键字不在方法签名里面,所以不涉及重载问题

*/

synchronizedlonggetValue(){

returnsuper.countValue;

}

@Override

synchronizedvoidsumValue(){

super.countValue+=preInit[index++%round];

}

}

classLockTestextendsTestTemplate{

ReentrantLocklock=newReentrantLock();

publicLockTest(String_id,int_round,int_threadNum,CyclicBarrier_cb){

super(_id,_round,_threadNum,_cb);

}

/**

*synchronized关键字不在方法签名里面,所以不涉及重载问题

*/

@Override

longgetValue(){

try{

lock.lock();

returnsuper.countValue;

}finally{

lock.unlock();

}

}

@Override

voidsumValue(){

try{

lock.lock();

super.countValue+=preInit[index++%round];

}finally{

lock.unlock();

}

}

}

classAtomicTestextendsTestTemplate{

publicAtomicTest(String_id,int_round,int_threadNum,CyclicBarrier_cb){

super(_id,_round,_threadNum,_cb);

}

@Override

/**

*synchronized关键字不在方法签名里面,所以不涉及重载问题

*/

longgetValue(){

returnsuper.countValueAtmoic.get();

}

@Override

voidsumValue(){

super.countValueAtmoic.addAndGet(super.preInit[indexAtomic.get()%round]);

}

}

abstractclassTestTemplate{

privateStringid;

protectedintround;

privateintthreadNum;

protectedlongcountValue;

protectedAtomicLongcountValueAtmoic=newAtomicLong(0);

protectedint[]preInit;

protectedintindex;

protectedAtomicIntegerindexAtomic=newAtomicInteger(0);

Randomr=newRandom(47);

//任务栅栏,同批任务,先到达wait的任务挂起,一直等到全部任务到达制定的wait地点后,才能全部唤醒,继续执行

privateCyclicBarriercb;

publicTestTemplate(String_id,int_round,int_threadNum,CyclicBarrier_cb){

this.id=_id;

this.round=_round;

this.threadNum=_threadNum;

cb=_cb;

preInit=newint[round];

for(inti=0;i

preInit[i]=r.nextInt(100);

}

}

abstractvoidsumValue();

/*

*对long的操作是非原子的,原子操作只针对32位

*long是64位,底层操作的时候分2个32位读写,因此不是线程安全

*/

abstractlonggetValue();

publicvoidtestTime(){

ExecutorServicese=Executors.newCachedThreadPool();

longstart=System.nanoTime();

//同时开启2*ThreadNum个数的读写线程

for(inti=0;i

se.execute(newRunnable(){

pub

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 农林牧渔 > 林学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1