LockSynchoronized和ReentrantLock的使用Word格式文档下载.docx
- 文档编号:1516293
- 上传时间:2023-04-30
- 格式:DOCX
- 页数:16
- 大小:18.72KB
LockSynchoronized和ReentrantLock的使用Word格式文档下载.docx
《LockSynchoronized和ReentrantLock的使用Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《LockSynchoronized和ReentrantLock的使用Word格式文档下载.docx(16页珍藏版)》请在冰点文库上搜索。
简单来说,它有一个与锁相关的获取计数器,如果拥有锁的某个线程再次得到锁,那么获取计数器就加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<
threadNum;
j++){
executor.execute(newThread(){
@Override
publicvoidrun(){
for(inti=0;
i<
count;
i++){
test();
}
try{
barrier.await();
}catch(InterruptedExceptione){
e.printStackTrace();
}catch(BrokenBarrierExceptione){
}
});
}
try{
barrier.await();
}catch(InterruptedExceptione){
e.printStackTrace();
}catch(BrokenBarrierExceptione){
//所有线程执行完成之后,才会跑到这一步
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();
returnlockCounter;
}finally{
lock.unlock();
staticlonggetSync(){
synchronized(syncLock){
returnsyncCounter;
staticlonggetAtom(){
returnatomicCounter.get();
staticlonggetSemaphore()throwsInterruptedException{
mutex.acquire();
returnsemaCounter;
mutex.release();
staticlonggetLockInc(){
return++lockCounter;
staticlonggetSyncInc(){
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,
getLock();
staticclassSyncTestextendsTest{
publicSyncTest(Stringid,CyclicBarrierbarrier,longcount,
getSync();
staticclassAtomicTestextendsTest{
publicAtomicTest(Stringid,CyclicBarrierbarrier,longcount,
getAtom();
publicstaticvoidtest(Stringid,longcount,intthreadNum,
finalCyclicBarrierbarrier=newCyclicBarrier(threadNum+1,
newThread(){
@Override
publicvoidrun(){
});
System.out.println("
=============================="
);
count="
+count+"
/t"
+"
ThreadCount="
+threadNum);
newLockTest("
Lock"
barrier,COUNT,threadNum,executor).startTest();
newSyncTest("
Sync"
newAtomicTest("
Atom"
barrier,COUNT,threadNum,executor)
.startTest();
newSemaTest("
Sema"
publicstaticvoidmain(String[]args){
for(inti=1;
5;
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){
Sync"
round,threadNum,cyclicBarrier).testTime();
Lock"
Atom"
publicstaticvoidmain(Stringargs[]){
for(inti=0;
i<
5;
i++){
intround=100000*(i+1);
intthreadNum=5*(i+1);
CyclicBarriercb=newCyclicBarrier(threadNum*2+1);
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;
synchronizedvoidsumValue(){
super.countValue+=preInit[index++%round];
classLockTestextendsTestTemplate{
ReentrantLocklock=newReentrantLock();
publicLockTest(String_id,int_round,int_threadNum,CyclicBarrier_cb){
longgetValue(){
try{
lock.lock();
returnsuper.countValue;
}finally{
voidsumValue(){
super.countValue+=preInit[index++%round];
classAtomicTestextendsTestTemplate{
publicAtomicTest(String_id,int_round,int_threadNum,CyclicBarrier_cb){
returnsuper.countValueAtmoic.get();
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];
preInit.length;
preInit[i]=r.nextInt(100);
abstractvoidsumValue();
/*
*对long的操作是非原子的,原子操作只针对32位
*long是64位,底层操作的时候分2个32位读写,因此不是线程安全
abstractlonggetValue();
publicvoidtestTime(){
ExecutorServicese=Executors.newCachedThreadPool();
longstart=System.nanoTime();
//同时开启2*ThreadNum个数的读写线程
threadNum;
se.execute(newRunnable(){
pub
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- LockSynchoronized ReentrantLock 使用
![提示](https://static.bingdoc.com/images/bang_tan.gif)