永发信息网

多线程 synchrized和lock的区别

答案:2  悬赏:0  手机版
解决时间 2021-03-05 23:31
  • 提问者网友:放下
  • 2021-03-05 03:04
多线程 synchrized和lock的区别
最佳答案
  • 五星知识达人网友:空山清雨
  • 2021-03-05 03:16
虽然我很聪明,但这么说真的难到我了
全部回答
  • 1楼网友:鱼忧
  • 2021-03-05 03:32
BlockingQueue是多线程里面一个非常重要的数据结构。在面试的时候,也常会被问到怎么实现BlockingQueue。本篇根据Java7里ArrayBlockingQueue的源码,简单介绍一下如何实现一个BlockingQueue。要实现BlockingQueue,首先得了解最主要的方法:add()和remove()是最原始的方法,也是最不常用的。原因是,当队列满了或者空了的时候,会抛出IllegalStateException("Queuefull")/NoSuchElementException(),并不符合我们对阻塞队列的要求;因此,ArrayBlockingQueue里,这两个方法的实现,直接继承自java.util.AbstractQueue:1publicbooleanadd(Ee){2if(offer(e))3returntrue;4else5thrownewIllegalStateException("Queuefull");6}78publicEremove(){9Ex=poll();10if(x!=null)11returnx;12else13thrownewNoSuchElementException();14}有上述源码可知,add()和remove()实现的关键,是来自java.util.Queue接口的offer()和poll()方法。offer():在队列尾插入一个元素。若成功便返回true,若队列已满则返回false。(Thismethodisgenerallypreferabletomethodadd(java.lang.Object),whichcanfailtoinsertanelementonlybythrowinganexception.)poll():同理,取出并删除队列头的一个元素。若成功便返回true,若队列为空则返回false。这里使用的是ReentrantLock,在插入或者取出前,都必须获得队列的锁,以保证同步。1publicbooleanoffer(Ee){2checkNotNull(e);3finalReentrantLocklock=this.lock;4lock.lock();5try{6if(count==items.length)7returnfalse;8else{9insert(e);10returntrue;11}12}finally{13lock.unlock();14}15}1617publicEpoll(){18finalReentrantLocklock=this.lock;19lock.lock();20try{21return(count==0)?null:extract();22}finally{23lock.unlock();24}25}由于offer()/poll()是非阻塞方法,一旦队列已满或者已空,均会马上返回结果,也不能达到阻塞队列的目的。因此有了put()/take()这两个阻塞方法:1publicvoidput(Ee)throwsInterruptedException{2checkNotNull(e);3finalReentrantLocklock=this.lock;4lock.lockInterruptibly();5try{6while(count==items.length)7notFull.await();8insert(e);9}finally{10lock.unlock();11}12}1314publicEtake()throwsInterruptedException{15finalReentrantLocklock=this.lock;16lock.lockInterruptibly();17try{18while(count==0)19notEmpty.await();20returnextract();21}finally{22lock.unlock();23}24}put()/take()的实现,比起offer()/poll()复杂了一些,尤其有两个地方值得注意:1.取得锁以后,循环判断队列是否已满或者已空,并加上Condition的await()方法将当前正在调用put()的线程挂起,直至notFull.signal()唤起。2.这里使用的是lock.lockInterruptibly()而不是lock.lock()。原因在这里。lockInterruptibly()这个方法,优先考虑响应中断,而不是响应普通获得锁或重入获得锁。简单来说就是,由于put()/take()是阻塞方法,一旦有interruption发生,必须马上做出反应,否则可能会一直阻塞。最后,无论是offer()/poll()还是put()/take(),都要靠insert()/extract()这个私有方法去完成真正的工作:1privatevoidinsert(Ex){2items[putIndex]=x;3putIndex=inc(putIndex);4++count;5notEmpty.signal();6}78finalintinc(inti){9return(++i==items.length)?0:i;10}
我要举报
如以上回答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
点此我要举报以上问答信息
大家都在看
推荐资讯