来自:mjsws > 馆藏分类
配色: 字号:
Java Lock与Condition的理解 ReentrantLock锁的简单使用技巧
2018-06-22 | 阅:  转:  |  分享 
  
JavaLock与Condition的理解ReentrantLock锁的简单使用技巧LockReentrantLock是我们常用的锁,
日常我们都只使用了其中一部分功能如下:?1234567?ReentrantLocklock=newReentrantLoc
k();?lock.lock();?try{....?}finally{lock.unlock();?}实际上Java提供
的LinkedBlockingQueue类就是基于ReentrantLock与Condition结合使用的,这是很经典的生产与消费
场景,里面有两个锁putLock与takeLock锁。解决问题:取元素时takeLock已经获取到锁了,但是由于列队是空的,使用n
otEmpty.await()使当前线程处理等待状态,这时如果有新的线程调用take方法时,新的线程也能获取到锁,也会继续等待,当
put元素后,notEmpty.signal()发送信号,会唤醒其中一个等待线程。使用condition可以使线程交互变的更加灵
活,ReentrantLock可以定义公平锁与非公平锁,公平锁可以保证线程访问顺序,非公平锁不一定保证线程访问顺序,默认为非公平锁
。take方法?12345678910111213141516171819202122//每次取完之后使用自唤醒方法使其它等待线程
,多了一重信息通知,取完之后会调用notFull方法唤醒正在等写入的方法publicEtake()throwsInterr
uptedException{?Ex;?intc=-1;?finalAtomicIntegercount=thi
s.count;?finalReentrantLocktakeLock=this.takeLock;?takeLock.l
ockInterruptibly();//获取锁?try{while(count.get()==0){//如果当前元素为
0线程等待?notEmpty.await();}x=dequeue();//取一个元素c=count.getAndDecr
ement();//总数减1if(c>1)//如果有元素继续唤醒一个等待线程?notEmpty.signal();?}f
inally{takeLock.unlock();?}?if(c==capacity)signalNotFull();?r
eturnx;?}put方法?123456789101112131415161718192021publicvoidput(
Ee)throwsInterruptedException{?if(e==null)thrownewNullP
ointerException();?intc=-1;?Nodenode=newNode(e);?fin
alReentrantLockputLock=this.putLock;?finalAtomicIntegercoun
t=this.count;?putLock.lockInterruptibly();?try{?while(count.
get()==capacity){//列队满,等列队有空间notFull.await(www.482223.com);?}?
enqueue(node);//插入元素?c=count.getAndIncrement();//总数加1?if(c+1
.unlock();?}?if(c==0)//通知正在等待取元素的线程?signalNotEmpty();}

synchronized锁?12345678910synchronized(writeLock){?while(runThr
eadNum>=5){?try{System.out.println("threadNum:"+runThreadNu
m);writeLock.wait();?}catch(InterruptedExceptione){e.printSta
ckTrace();?}?}}测试代码实例?1234567891011121314151617181920212223242526
27282930313233343536373839404142434445464748495051525354555657585
9606162636465666768697071727374757677787980818283848586878889impo
rtjava.util.Date;importjava.util.concurrent.atomic.AtomicIntege
r;importjava.util.concurrent.locks.Condition;importjava.util.co
ncurrent.locks.ReentrantLock;?/?Createdbyzengrenyuanon18/
6/11.?/publicclassTestLock{??publicstaticfinalintmaxNum=
1;?privatefinalReentrantLocklock=newReentrantLock();?priva
tefinalConditionnotFull=lock.newCondition();?privatefinalC
onditionnotEmpty=lock.newCondition();?privateAtomicIntegerco
unt=newAtomicInteger(0);??publicstaticvoidmain(String[]arg
s)throwsInterruptedException{?finalTestLocktestLock=newTe
stLock();?testLock.putThread("线程1");?testLock.putThread("线程2");?t
estLock.putThread("线程3");?testLock.putThread("线程4");?testLock.put
Thread("线程5");?testLock.readThread("读线程");?}??publicvoidreadThr
ead(Stringname){?Threadthread=newThread(newRunnable(){@Ov
erridepublicvoidrun(){?while(true){?try{read();?}catch(In
terruptedExceptione){e.printStackTrace(www.267774.com);?}?}}?})
;?thread.setName(name);?thread.start();???}??publicvoidread()t
hrowsInterruptedException{?lock.lock();?try{while(count.get()
==0){?notEmpty.await();}System.out.println("read:"+count.dec
rementAndGet());notFull.signal();?}finally{lock.unlock();?}?}??
?publicvoidputThread(Stringname){?Threadthread=newThread(
newRunnable(){@Overridepublicvoidrun(){?try{?print();?}cat
ch(InterruptedExceptione){?e.printStackTrace();?}}?});?thread.
setName(name);?thread.start(www.rodlg.com);?}??publicvoidprint(
)throwsInterruptedException{?lock.lock();?try{System.out.prin
tln("threadName"+Thread.currentThread().getName());while(count
.get()==maxNum){?notFull.await();}System.out.println("put:"+count.getAndIncrement()+"threadName"+Thread.currentThread().getName());System.out.println(MiscUtils.formatDate(newDate(),MiscUtils.STANDARDPATTERN));notEmpty.signal();?}finally{lock.unlock();?}?}}
献花(0)
+1
(本文系mjsws首藏)