Lock与synchronized的区别

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

Lock与synchronized的区别LockSynchronizedReentrantLock线程区别多次思考过这个问题,都没有形成理论,今天有时间了,我把他总结出来,希望对大家有所帮助1、ReentrantLock拥有Synchronized相同的并发性和内存语义,此外还多了锁投票,定时锁等候和中断锁等候线程A和B都要获取对象O的锁定,假设A获取了对象O锁,B将等待A释放对O的锁定,如果使用synchronized,如果A不释放,B将一直等下去,不能被中断如果使用ReentrantLock,如果A不释放,可以使B在等待了足够长的时间以后,中断等待,而干别的事情ReentrantLock获取锁定与三种方式:a)lock(),如果获取了锁立即返回,如果别的线程持有锁,当前线程则一直处于休眠状态,直到获取锁b)tryLock(),如果获取了锁立即返回true,如果别的线程正持有锁,立即返回false;c)tryLock(longtimeout,TimeUnitunit),如果获取了锁定立即返回true,如果别的线程正持有锁,会等待参数给定的时间,在等待的过程中,如果获取了锁定,就返回true,如果等待超时,返回false;d)lockInterruptibly:如果获取了锁定立即返回,如果没有获取锁定,当前线程处于休眠状态,直到或者锁定,或者当前线程被别的线程中断2、synchronized是在JVM层面上实现的,不但可以通过一些监控工具监控synchronized的锁定,而且在代码执行时出现异常,JVM会自动释放锁定,但是使用Lock则不行,lock是通过代码实现的,要保证锁定一定会被释放,就必须将unLock()放到finally{}中3、在资源竞争不是很激烈的情况下,Synchronized的性能要优于ReetrantLock,但是在资源竞争很激烈的情况下,Synchronized的性能会下降几十倍,但是ReetrantLock的性能能维持常态;下面内容是转载的多线程任务包对于同步的性能方面有了很大的改进,在原有synchronized关键字的基础上,又增加了ReentrantLock,以及各种Atomic类。了解其性能的优劣程度,有助与我们在特定的情形下做出正确的选择。总体的结论先摆出来:synchronized:在资源竞争不是很激烈的情况下,偶尔会有同步的情形下,synchronized是很合适的。原因在于,编译程序通常会尽可能的进行优化synchronize,另外可读性非常好,不管用没用过5.0多线程包的程序员都能理解。ReentrantLock:ReentrantLock提供了多样化的同步,比如有时间限制的同步,可以被Interrupt的同步(synchronized的同步是不能Interrupt的)等。在资源竞争不激烈的情形下,性能稍微比synchronized差点点。但是当同步非常激烈的时候,synchronized的性能一下子能下降好几十倍。而ReentrantLock确还能维持常态。Atomic:和上面的类似,不激烈情况下,性能比synchronized略逊,而激烈的时候,也能维持常态。激烈的时候,Atomic的性能会优于ReentrantLock一倍左右。但是其有一个缺点,就是只能同步一个值,一段代码中只能出现一个Atomic的变量,多于一个同步无效。因为他不能在多个Atomic之间同步。所以,我们写同步的时候,优先考虑synchronized,如果有特殊需要,再进一步优化。ReentrantLock和Atomic如果用的不好,不仅不能提高性能,还可能带来灾难。先贴测试结果:再贴代码(Atomic测试代码不准确,一个同步中只能有1个Actomic,这里用了2个,但是这里的测试只看速度)==========================round:100000thread:5Sync=35301694Lock=56255753Atom=43467535==========================round:200000thread:10Sync=110514604Lock=204235455Atom=170535361==========================round:300000thread:15Sync=253123791Lock=448577123Atom=362797227==========================round:400000thread:20Sync=16562148262Lock=846454786Atom=667947183==========================round:500000thread:25Sync=26932301731Lock=1273354016Atom=982564544代码如下:Java代码1.packagetest.thread;2.3.importstaticjava.lang.System.out;4.5.importjava.util.Random;6.importjava.util.concurrent.BrokenBarrierException;7.importjava.util.concurrent.CyclicBarrier;8.importjava.util.concurrent.ExecutorService;9.importjava.util.concurrent.Executors;10.importjava.util.concurrent.atomic.AtomicInteger;11.importjava.util.concurrent.atomic.AtomicLong;12.importjava.util.concurrent.locks.ReentrantLock;13.14.publicclassTestSyncMethods{15.16.publicstaticvoidtest(intround,intthreadNum,CyclicBarriercyclicBarrier){17.newSyncTest(Sync,round,threadNum,cyclicBarrier).testTime();18.newLockTest(Lock,round,threadNum,cyclicBarrier).testTime();19.newAtomicTest(Atom,round,threadNum,cyclicBarrier).testTime();20.}21.22.publicstaticvoidmain(Stringargs[]){23.24.for(inti=0;i5;i++){25.intround=100000*(i+1);26.intthreadNum=5*(i+1);27.CyclicBarriercb=newCyclicBarrier(threadNum*2+1);28.out.println(==========================);29.out.println(round:+round+thread:+threadNum);30.test(round,threadNum,cb);31.32.}33.}34.}35.36.classSyncTestextendsTestTemplate{37.publicSyncTest(String_id,int_round,int_threadNum,CyclicBarrier_cb){38.super(_id,_round,_threadNum,_cb);39.}40.@Override41./**42.*synchronized关键字不在方法签名里面,所以不涉及重载问题43.*/44.synchronizedlonggetValue(){45.returnsuper.countValue;46.}47.@Override48.synchronizedvoidsumValue(){49.super.countValue+=preInit[index++%round];50.}51.}52.53.54.classLockTestextendsTestTemplate{55.ReentrantLocklock=newReentrantLock();56.publicLockTest(String_id,int_round,int_threadNum,CyclicBarrier_cb){57.super(_id,_round,_threadNum,_cb);58.}59./**60.*synchronized关键字不在方法签名里面,所以不涉及重载问题61.*/62.@Override63.longgetValue(){64.try{65.lock.lock();66.returnsuper.countValue;67.}finally{68.lock.unlock();69.}70.}71.@Override72.voidsumValue(){73.try{74.lock.lock();75.super.countValue+=preInit[index++%round];76.}finally{77.lock.unlock();78.}79.}80.}81.82.83.classAtomicTestextendsTestTemplate{84.publicAtomicTest(String_id,int_round,int_threadNum,CyclicBarrier_cb){85.super(_id,_round,_threadNum,_cb);86.}87.@Override88./**89.*synchronized关键字不在方法签名里面,所以不涉及重载问题90.*/91.longgetValue(){92.returnsuper.countValueAtmoic.get();93.}94.@Override95.voidsumValue(){96.super.countValueAtmoic.addAndGet(super.preInit[indexAtomic.get()%round]);97.}98.}99.abstractclassTestTemplate{100.privateStringid;101.protectedintround;102.privateintthreadNum;103.protectedlongcountValue;104.protectedAtomicLongcountValueAtmoic=newAtomicLong(0);105.protectedint[]preInit;106.protectedintindex;107.protectedAtomicIntegerindexAtomic=newAtomicInteger(0);108.Randomr=newRandom(47);109.//任务栅栏,同批任务,先到达wait的任务挂起,一直等到全部任务到达制定的wait地点后,才能全部唤醒,继续执行110.privateCyclicBarriercb;111.publicTestTemplate(String_id,int_round,int_threadNum,CyclicBarrier_cb){112.this.id=_id;113.this.round=_round;114.this.threadNum=_threadNum;115.cb=_cb;116.preInit=newint[round];117.for(inti=0;ipreInit.length;i++){118.preInit[i]=r.nextInt(100);119.}120.}121

1 / 7
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功