亚洲情人网-亚洲情人-亚洲欧洲综合-亚洲欧洲自拍-欧美专区亚洲

locklock(locklock水杯)

  • 生活
  • 2023-04-21 15:43

ReentrantLock

ReentrantLock,一個(gè)可重入的互斥鎖,它具有與使用synchronized***和語(yǔ)句所訪問(wèn)的隱式監(jiān)視器鎖相同的一些基本行為和語(yǔ)義,但功能更強(qiáng)大。

ReentrantLock基本用法

先來(lái)看一下ReentrantLock的基本用法:

publicclassThreadDomain38{privateLocklock=newReentrantLock();publicvoidtestMethod(){try{lock.lock();for(inti=0;i<2;i++){System.out.println("ThreadName="+Thread.currentThread().getName()+",i="+i);}}finally{lock.unlock();}}}publicclassMyThread38extendsThread{privateThreadDomain38td;publicMyThread38(ThreadDomain38td){this.td=td;}publicvoidrun(){td.testMethod();}}publicstaticvoidmain(String[]args){ThreadDomain38td=newThreadDomain38();MyThread38mt0=newMyThread38(td);MyThread38mt1=newMyThread38(td);MyThread38mt2=newMyThread38(td);mt0.start();mt1.start();mt2.start();}

看一下運(yùn)行結(jié)果:

ThreadName=Thread-1,i=0ThreadName=Thread-1,i=1ThreadName=Thread-0,i=0ThreadName=Thread-0,i=1ThreadName=Thread-2,i=0ThreadName=Thread-2,i=1

沒(méi)有任何的交替,數(shù)據(jù)都是分組打印的,說(shuō)明了一個(gè)線程打印完畢之后下一個(gè)線程才可以獲得鎖去打印數(shù)據(jù),這也證明了ReentrantLock具有加鎖的功能

ReentrantLock持有的是對(duì)象監(jiān)視器

前面已經(jīng)證明了ReentrantLock具有加鎖功能,但我們還不知道ReentrantLock持有的是什么鎖,因此寫個(gè)例子看一下:

publicclassThreadDomain39{privateLocklock=newReentrantLock();publicvoidmethodA(){try{lock.lock();System.out.println("MethodAbeginThreadName="+Thread.currentThread().getName());Thread.sleep(5000);System.out.println("MethodAendThreadName="+Thread.currentThread().getName());}catch(InterruptedExceptione){e.printStackTrace();}finally{lock.unlock();}}publicvoidmethodB(){lock.lock();System.out.println("MethodBbeginThreadName="+Thread.currentThread().getName());System.out.println("MethodBbeginThreadName="+Thread.currentThread().getName());lock.unlock();}}

寫兩個(gè)線程分別調(diào)用methodA()和methodB()***:

publicclassMyThread39_0extendsThread{privateThreadDomain39td;publicMyThread39_0(ThreadDomain39td){this.td=td;}publicvoidrun(){td.methodA();}}publicclassMyThread39_1extendsThread{privateThreadDomain39td;publicMyThread39_1(ThreadDomain39td){this.td=td;}publicvoidrun(){td.methodB();}}

寫一個(gè)main函數(shù)啟動(dòng)這兩個(gè)線程:

publicstaticvoidmain(String[]args){ThreadDomain39td=newThreadDomain39();MyThread39_0mt0=newMyThread39_0(td);MyThread39_1mt1=newMyThread39_1(td);mt0.start();mt1.start();}

看一下運(yùn)行結(jié)果:

MethodBbeginThreadName=Thread-1MethodBbeginThreadName=Thread-1MethodAbeginThreadName=Thread-0MethodAendThreadName=Thread-0

看不見時(shí)間,不過(guò)第四確實(shí)是格了5秒左右才打印出來(lái)的。從結(jié)果來(lái)看,已經(jīng)證明了ReentrantLock持有的是對(duì)象監(jiān)視器,可以寫一段代碼進(jìn)一步證明這一結(jié)論,即去掉methodB()內(nèi)部和鎖相關(guān)的代碼,只留下兩句打印語(yǔ)句:

MethodAbeginThreadName=Thread-0MethodBbeginThreadName=Thread-1MethodBbeginThreadName=Thread-1MethodAendThreadName=Thread-0

看到交替打印了,進(jìn)一步證明了ReentrantLock持有的是"對(duì)象監(jiān)視器"的結(jié)論。

不過(guò)注意一點(diǎn),ReentrantLock雖然持有對(duì)象監(jiān)視器,但是和synchronized持有的對(duì)象監(jiān)視器不是一個(gè)意思,雖然我也不清楚兩個(gè)持有的對(duì)象監(jiān)視器有什么區(qū)別,不過(guò)把methodB()***用synchronized修飾,methodA()不變,兩個(gè)***還是異步運(yùn)行的,所以就記一個(gè)結(jié)論吧----ReentrantLock和synchronized持有的對(duì)象監(jiān)視器不同。

另外,千萬(wàn)別忘了,ReentrantLock持有的鎖是需要手動(dòng)去unlock()的

Condition

synchronized與wait()和nitofy()/notifyAll()***相結(jié)合可以實(shí)現(xiàn)等待/通知模型,ReentrantLock同樣可以,但是需要借助Condition,且Condition有更好的靈活性,具體體現(xiàn)在:

1、一個(gè)Lock里面可以創(chuàng)建多個(gè)Condition實(shí)例,實(shí)現(xiàn)多路通知

2、notify()***進(jìn)行通知時(shí),被通知的線程時(shí)Java虛擬機(jī)隨機(jī)選擇的,但是ReentrantLock結(jié)合Condition可以實(shí)現(xiàn)有選擇性地通知,這是非常重要的

看一下利用Condition實(shí)現(xiàn)等待/通知模型的最簡(jiǎn)單用法,下面的代碼注意一下,await()和signal()之前,必須要先lock()獲得鎖,使用完畢在finally中unlock()釋放鎖,這和wait()/notify()/notifyAll()使用前必須先獲得對(duì)象鎖是一樣的:

publicclassThreadDomain40{privateLocklock=newReentrantLock();privateConditioncondition=lock.newCondition();publicvoidawait(){try{lock.lock();System.out.println("await時(shí)間為:"+System.currentTimeMillis());condition.await();System.out.println("await等待結(jié)束");}catch(InterruptedExceptione){e.printStackTrace();}finally{lock.unlock();}}publicvoidsignal(){try{lock.lock();System.out.println("signal時(shí)間為:"+System.currentTimeMillis());condition.signal();}finally{lock.unlock();}}}publicclassMyThread40extendsThread{privateThreadDomain40td;publicMyThread40(ThreadDomain40td){this.td=td;}publicvoidrun(){td.await();}}publicstaticvoidmain(String[]args)throwsException{ThreadDomain40td=newThreadDomain40();MyThread40mt=newMyThread40(td);mt.start();Thread.sleep(3000);td.signal();}

看一下運(yùn)行結(jié)果:

await時(shí)間為:1443970329524signal時(shí)間為:1443970332524await等待結(jié)束

差值是3000毫秒也就是3秒,符合代碼預(yù)期,成功利用ReentrantLock的Condition實(shí)現(xiàn)了等待/通知模型。其實(shí)這個(gè)例子還證明了一點(diǎn),Condition的await()***是釋放鎖的,原因也很簡(jiǎn)單,要是await()***不釋放鎖,那么signal()***又怎么能調(diào)用到Condition的signal()***呢?

注意要是用一個(gè)Condition的話,那么多個(gè)線程被該Condition給await()后,調(diào)用Condition的signalAll()***喚醒的是所有的線程。如果想單獨(dú)喚醒部分線程該怎么辦呢?new出多個(gè)Condition就可以了,這樣也有助于提升程序運(yùn)行的效率。使用多個(gè)Condition的場(chǎng)景是很常見的,像ArrayBlockingQueue里就有。

猜你喜歡

主站蜘蛛池模板: 综合精品 | 自拍偷拍亚洲第一页 | 综合网久久| 综合久久久久久久综合网 | 国产黄色免费看 | 国产欧美一区二区久久 | 中文字幕久久久久 | 久久成人性色生活片 | 性夜影院爽黄a爽免费视频 在线观看免费视频国产 | 五月婷婷激情五月 | 四虎影视永久地址www成人 | 亚洲综合在线视频 | 亚洲精品第一 | 亚洲天堂男人在线 | 在线亚洲电影 | 亚洲免费一级片 | 五月综合久久 | 国产精品亚洲一区二区三区久久 | 亚洲中字幕永久在线观看 | 欧美在线视频二区 | 国产大学生自拍视频 | 亚洲国产成人久久一区www | 久久精品国产69国产精品亚洲 | 精品国产免费久久久久久 | 免费观看男女羞羞的视频网站 | 自拍偷拍欧美视频 | 在线一区二区三区 | 色婷五月 | 亚洲精品第一国产综合野 | 欧美精品福利视频 | 亚洲女人在线 | 久久国产欧美另类久久久 | 四虎国产精品永久地址49 | 99视频精品全部免费免费观 | 国内精品视频一区 | 国内精品久久久久影院亚洲 | 亚洲精品乱码久久久久久蜜桃欧美 | 黑人一区| 黄色国产片| 精品国内在线视频2019百度 | 午夜免费视频福利集合100 |