观看麻豆影视文化有限公司-国产 高清 在线-国产 日韩 欧美 亚洲-国产 日韩 欧美 综合-日日夜夜免费精品视频-日日夜夜噜

locklock(locklock水杯)

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

ReentrantLock

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

ReentrantLock基本用法

先來看一下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

沒有任何的交替,數(shù)據(jù)都是分組打印的,說明了一個(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í)間,不過第四確實(shí)是格了5秒左右才打印出來的。從結(jié)果來看,已經(jīng)證明了ReentrantLock持有的是對(duì)象監(jiān)視器,可以寫一段代碼進(jìn)一步證明這一結(jié)論,即去掉methodB()內(nèi)部和鎖相關(guān)的代碼,只留下兩句打印語句:

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

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

不過注意一點(diǎn),ReentrantLock雖然持有對(duì)象監(jiān)視器,但是和synchronized持有的對(duì)象監(jiān)視器不是一個(gè)意思,雖然我也不清楚兩個(gè)持有的對(duì)象監(jiān)視器有什么區(qū)別,不過把methodB()***用synchronized修飾,methodA()不變,兩個(gè)***還是異步運(yùn)行的,所以就記一個(gè)結(jié)論吧----ReentrantLock和synchronized持有的對(duì)象監(jiā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)等待/通知模型的最簡單用法,下面的代碼注意一下,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()***是釋放鎖的,原因也很簡單,要是await()***不釋放鎖,那么signal()***又怎么能調(diào)用到Condition的signal()***呢?

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

猜你喜歡

主站蜘蛛池模板: 亚洲综合图片人成综合网 | 一级片免费在线 | 久久99精品这里精品3 | 亚洲aⅴ男人的天堂在线观看 | 日韩视频观看 | 国产成人亚洲综合91精品555 | 孕妇一级片 | 美女张开腿让男人捅的视频 | 国内精品久久久久久 | 国产三级a三级三级天天 | 欧美日韩国产高清一区二区三区 | 国产手机在线国内精品 | 一级视频在线播放 | 色九九 | 久久久久性| 91久久另类重口变态 | 亚洲精品成人在线 | 欧美在线播放成人免费 | 久在线观看视频 | 国产精品综合一区二区三区 | 91国在线高清视频 | 黄色美女一级片 | 日韩在线精品视频 | 亚洲毛片在线看 | 欧美一级专区免费大片野外交 | 国产欧美一区二区三区在线看 | 成人精品一区二区www | 亚洲成人精品久久 | 韩国免又爽又刺激激情视频 | 男女视频免费看 | 欧美人一级淫片a免费播放 欧美人与z0z0xxxx | 黄色三级毛片 | 精品国产91在线网 | 国产私拍福利精品视频推出 | 黄色毛片在线 | 午夜爽爽爽视频 | 美欧毛片 | 亚洲美女精品视频 | 久久91精品国产91久久户 | 91九色精品国产免费 | 欧美一级看片免费观看视频在线 |