基于Spring Boot的线程池监控问题如何解决


这篇文章主要介绍“基于SpringBoot的线程池监控问题如何解决”,在日常操作中,相信很多人在基于SpringBoot的线程池监控问题如何解决问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”基于SpringBoot的线程池监控问题如何解决”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!Java线程池作为最常使用到的并发工具,相信大家都不陌生,但是你真的确定使用对了吗?大名鼎鼎的阿里Java代码规范要求我们不使用 Executors来快速创建线程池,但是抛弃Executors,使用其它方式创建线程池就一定不会出现问题吗?本质上对于我们来说线程池本身的运行过程是一个黑盒,我们没办法了解线程池中的运行状态时,出现问题没有办法及时判断和预警。面对这种黑盒操作必须通过监控方式让其透明化,这样对我们来说才能更好的使用好线程池。因此必须对线程池做监控。对于如何做监控,本质就是涉及三点,分别是数据采集、数据存储以及大盘的展示,接下来我们分说下这三点;采集什么数据,对于我们来说需要采集就是黑盒的数据,什么又是线程池的黑盒数据,其实也就是整个线程处理的整个流程,在整个流程中,我们可以通过ThreadPoolExecutor中的七个方法获取数据,通过这七个方法采集到的数据就可以使线程池的执行过程透明化。getCorePoolSize():获取核心线程数;getMaximumPoolSize:获取最大线程数;getQueue():获取线程池中的阻塞队列,并通过阻塞队列中的方法获取队列长度、元素个数等;getPoolSize():获取线程池中的工作线程数(包括核心线程和非核心线程);getActiveCount():获取活跃线程数,也就是正在执行任务的线程;getLargestPoolSize():获取线程池曾经到过的最大工作线程数;getTaskCount():获取历史已完成以及正在执行的总的任务数量;除了我们了解的这些流程以外,ThreadPoolExecutor中还提供了三种钩子函数,beforeExecute():Worker线程执行任务之前会调用的方法;afterExecute():在Worker线程执行任务之后会调用的方法;terminated():当线程池从运行状态变更到TERMINATED状态之前调用的方法;对于beforeExecute和afterExecute可以理解为使用Aop监听线程执行的时间,这样子我们可以对每个线程运行的时间整体做监控,terminated可以理解为线程关闭时候的监控,这样我们就可以整体获取采集到线程池生命周期的所有数据了。对于存储我们这个比较适合采用时序性数据库,此外现在很多成熟的监控产品都可以满足我们大屏展示的诉求,这里推荐下美团Cat和Prometheus,这里不展开进行讲解,大家可以根据自己公司的监控产品进行选择,对于不同的方案采取的存储形式会有些差异,甚至自己都可以自定义实现一个功能,反正难度不大。在实际的项目开发中我们会遇到以下场景:不同的业务采用同一个线程池,这样如果某个服务阻塞,会影响到整体共用线程池的所有服务,会触发线程池的拒绝策略;流量突然增加,需要动态调整线程池的参数,这个时候又不能重启;针对这两种场景,我们对线程池再次进行了深入的思考:如何合理配置线程池参数;如何动态调整线程池参数;如何给不同的服务之间做线程池的隔离;关于这个问题面试的时候也是经常被问到,我只能说这个问题开始就是一个坑,针对与CPU密集型和I/O密集型,线程池的参数是有不同设计的,也不是遵守几个公式就可以搞定,当然可以参考,我认为对于线程池合理的参数的配置是经过多次调整得到的,甚至增加和减少业务都会影响一些参数,我不太建议大家每天背书式的CPU密集型就是N+1,非CPU密集型就是2N,因此我们更希望看到线程池动态配置。关于如何动态调整线程池,还是回到我们场景问题的解决上,对于流量突增核心就是提升线程池的处理速度,那如何提升线程池的处理速度,有两种方式,一种是加快业务的处理,也就是消费的快,显然这种在运行的业务中我们想改变还是比较困难,这个可以作为复盘的重点;还有一种就是增加消费者,增加消费者的重点就是调整核心线程数以及非核心线程数的数量。居于这种思考,这个时候我们需要看下ThreadPoolExecutor线程池源码,首先看下开始定义的变量,通过变量的设计我们就会发现大师就是大师,大师通过AtomicInteger修饰的ctl变量,高3位存储了线程池的状态,低29存储线程的个数,通过一个变量完成两件事情,完成状态判断以及限制线程最大个数。使用一个HashSet存储Worker的引用,而Worker继承了AbstractQueuedSynchronizer,实现一个一个不可冲入的独占锁保证线程的安全性。我们的重点看的是volatile修饰的corePoolSize、maximumPoolSize以及keepAliveTime,当然threadFactory和handler也可以看下,不过这两个不是我们解决动态调整线程池的关键。对于这些volatile修饰的关键的变量,从并发角度思考的,必然是有并发读写的操作才使用volatile修饰的,在指标采集中我们看到其get的方法,对于写的操作我们可以猜测肯定提供了set的方式,这个时候我们可以搜索下setCorePoolSize,果不其然我们真的搜索到了。接下来我们看下interruptIdleWorkers的源码,此处源码使用ReentrantLock可重入锁,因为Worker的是通过一个全局的HashSer存储,这里通过ReentrantLock保证线程安全。接下来我们在验证一下是否存在其他相关的参数设置,如下:这里我们会发现一个问题BlockingQueue的队列容量不能修改,看到美团的文章提供的一个可修改的队列ResizableCapacityLinkedBlockingQueue,于是乎去看了一下LinkedBlockingQueue的源码,发现了关于capacity是一个final修饰的,这个时候我就思考一番,这个地方采用volatile修饰,对外暴露可修改,这样就实现了动态修改阻塞队列的大小。关于如何给不同服务之间做线程池的隔离,这里我们可以采用Hystrix的舱壁模式,也就是说针对不同服务类型的服务单独创建线程池,这样就可以实现服务之间不相互影响,不会因为某个服务导致整体的服务影响都阻塞。聊了这么多前置的知识储备,接下来我们来聊聊实现方案,整体的实现方案我们建立在Spring Boot的基础实现,采用Spring Cloud刷新动态配置,采用该方式比较合适单体应用,对于有Appllo和Nacos可以通过监听配置方式的来动态刷新。Maven依赖如下;配置信息如下:自定可修改阻塞队列大小的方式如下:Thismethodisequivalentto{@link#addLast}.
*
*@throwsIllegalStateExceptionifthisdequeisfull
*@throwsNullPointerExceptionifthespecifiedelementisnull
*/
@Override
publicbooleanadd(Ee){
addLast(e);
returntrue;
}

/**
*@throwsNullPointerExceptionifthespecifiedelementisnull
*/
@Override
publicbooleanoffer(Ee){
returnofferLast(e);
}

/**
*@throwsNullPointerException{@inheritDoc}
*@throwsInterruptedException{@inheritDoc}
*/
@Override
publicvoidput(Ee)throwsInterruptedException{
putLast(e);
}

/**
*@throwsNullPointerException{@inheritDoc}
*@throwsInterruptedException{@inheritDoc}
*/
@Override
publicbooleanoffer(Ee,longtimeout,TimeUnitunit)
throwsInterruptedException{
returnofferLast(e,timeout,unit);
}

/**
*Retrievesandremovestheheadofthequeuerepresentedbythisdeque.
*Thismethoddiffersfrom{@link#pollpoll}onlyinthatitthrowsan
*exceptionifthisdequeisempty.
*
*Thismethodisequivalentto{@link#removeFirst()removeFirst}.
*
*@returntheheadofthequeuerepresentedbythisdeque
*@throwsNoSuchElementExceptionifthisdequeisempty
*/
@Override
publicEremove(){
returnremoveFirst();
}

@Override
publicEpoll(){
returnpollFirst();
}

@Override
publicEtake()throwsInterruptedException{
returntakeFirst();
}

@Override
publicEpoll(longtimeout,TimeUnitunit)throwsInterruptedException{
returnpollFirst(timeout,unit);
}

/**
*Retrieves,butdoesnotremove,theheadofthequeuerepresentedby
*thisdeque.Thismethoddiffersfrom{@link#peekpeek}onlyinthat
*itthrowsanexceptionifthisdequeisempty.
*
*Thismethodisequivalentto{@link#getFirst()getFirst}.
*
*@returntheheadofthequeuerepresentedbythisdeque
*@throwsNoSuchElementExceptionifthisdequeisempty
*/
@Override
publicEelement(){
returngetFirst();
}

@Override
publicEpeek(){
returnpeekFirst();
}

/**
*Returnsthenumberofadditionalelementsthatthisdequecanideally
*(intheabsenceofmemoryorresourceconstraints)acceptwithout
*blocking.Thisisalwaysequaltotheinitialcapacityofthisdeque
*lessthecurrent{@codesize}ofthisdeque.
*
*Notethatyoucannotalwaystellifanattempttoinsert
*anelementwillsucceedbyinspecting{@coderemainingCapacity}
*becauseitmaybethecasethatanotherthreadisaboutto
*insertorremoveanelement.
*/
@Override
publicintremainingCapacity(){
finalReentrantLocklock=this.lock;
lock.lock();
try{
returncapacity-count;
}finally{
lock.unlock();
}
}

/**
*@throwsUnsupportedOperationException{@inheritDoc}
*@throwsClassCastException{@inheritDoc}
*@throwsNullPointerException{@inheritDoc}
*@throwsIllegalArgumentException{@inheritDoc}
*/
@Override
publicintdrainTo(CollectionsuperE>c){
returndrainTo(c,Integer.MAX_VALUE);
}

/**
*@throwsUnsupportedOperationException{@inheritDoc}
*@throwsClassCastException{@inheritDoc}
*@throwsNullPointerException{@inheritDoc}
*@throwsIllegalArgumentException{@inheritDoc}
*/
@Override
publicintdrainTo(CollectionsuperE>c,intmaxElements){
if(c==null){
thrownewNullPointerException();
}
if(c==this){
thrownewIllegalArgumentException();
}
if(maxElementsThismethodisequivalentto
*{@link#removeFirstOccurrence(Object)removeFirstOccurrence}.
*
*@paramoelementtoberemovedfromthisdeque,ifpresent
*@return{@codetrue}ifthisdequechangedasaresultofthecall
*/
@Override
publicbooleanremove(Objecto){
returnremoveFirstOccurrence(o);
}

/**
*Returnsthenumberofelementsinthisdeque.
*
*@returnthenumberofelementsinthisdeque
*/
@Override
publicintsize(){
finalReentrantLocklock=this.lock;
lock.lock();
try{
returncount;
}finally{
lock.unlock();
}
}

/**
*Returns{@codetrue}ifthisdequecontainsthespecifiedelement.
*Moreformally,returns{@codetrue}ifandonlyifthisdequecontains
*atleastoneelement{@codee}suchthat{@codeo.equals(e)}.
*
*@paramoobjecttobecheckedforcontainmentinthisdeque
*@return{@codetrue}ifthisdequecontainsthespecifiedelement
*/
@Override
publicbooleancontains(Objecto){
if(o==null){
returnfalse;
}
finalReentrantLocklock=this.lock;
lock.lock();
try{
for(Nodep=first;p!=null;p=p.next){
if(o.equals(p.item)){
returntrue;
}
}
returnfalse;
}finally{
lock.unlock();
}
}

/*
*TODO:Addsupportformoreefficientbulkoperations.
*
*Wedon’twanttoacquirethelockforeveryiteration,butwe
*alsowantotherthreadsachancetointeractwiththe
*collection,especiallywhencountisclosetocapacity.
*/

///**
//*Addsalloftheelementsinthespecifiedcollectiontothis
//*queue.AttemptstoaddAllofaqueuetoitselfresultin
//*{@codeIllegalArgumentException}.Further,thebehaviorof
//*thisoperationisundefinedifthespecifiedcollectionis
//*modifiedwhiletheoperationisinprogress.
//*
//*@paramccollectioncontainingelementstobeaddedtothisqueue
//*@return{@codetrue}ifthisqueuechangedasaresultofthecall
//*@throwsClassCastException{@inheritDoc}
//*@throwsNullPointerException{@inheritDoc}
//*@throwsIllegalArgumentException{@inheritDoc}
//*@throwsIllegalStateExceptionifthisdequeisfull
//*@see#add(Object)
//*/
//publicbooleanaddAll(CollectionextendsE>c){
//if(c==null)
//thrownewNullPointerException();
//if(c==this)
//thrownewIllegalArgumentException();
//finalReentrantLocklock=this.lock;
//lock.lock();
//try{
//booleanmodified=false;
//for(Ee:c)
//if(linkLast(e))
//modified=true;
//returnmodified;
//}finally{
//lock.unlock();
//}
//}

/**
*Returnsanarraycontainingalloftheelementsinthisdeque,in
*propersequence(fromfirsttolastelement).
*
*

Thereturnedarraywillbe”safe”inthatnoreferencestoitare
*maintainedbythisdeque.(Inotherwords,thismethodmustallocate
*anewarray).Thecalleristhusfreetomodifythereturnedarray.
*
*

Thismethodactsasbridgebetweenarray-basedandcollection-based
*APIs.
*
*@returnanarraycontainingalloftheelementsinthisdeque
*/
@Override
@SuppressWarnings(“unchecked”)
publicObject[]toArray(){
finalReentrantLocklock=this.lock;
lock.lock();
try{
Object[]a=newObject[count];
intk=0;
for(Nodep=first;p!=null;p=p.next){
a[k++]=p.item;
}
returna;
}finally{
lock.unlock();
}
}

/**
*Returnsanarraycontainingalloftheelementsinthisdeque,in
*propersequence;theruntimetypeofthereturnedarrayisthatof
*thespecifiedarray.Ifthedequefitsinthespecifiedarray,it
*isreturnedtherein.Otherwise,anewarrayisallocatedwiththe
*runtimetypeofthespecifiedarrayandthesizeofthisdeque.
*
*

Ifthisdequefitsinthespecifiedarraywithroomtospare
*(i.e.,thearrayhasmoreelementsthanthisdeque),theelementin
*thearrayimmediatelyfollowingtheendofthedequeissetto
*{@codenull}.
*
*

Likethe{@link#toArray()}method,thismethodactsasbridgebetween
*array-basedandcollection-basedAPIs.Further,thismethodallows
*precisecontrolovertheruntimetypeoftheoutputarray,andmay,
*undercertaincircumstances,beusedtosaveallocationcosts.
*
*

Suppose{@codex}isadequeknowntocontainonlystrings.
*Thefollowingcodecanbeusedtodumpthedequeintoanewly
*allocatedarrayof{@codeString}:
*
*

{@codeString[]y=x.toArray(newString[0]);}

*

*Notethat{@codetoArray(newObject[0])}isidenticalinfunctionto
*{@codetoArray()}.
*
*@paramathearrayintowhichtheelementsofthedequeareto
*bestored,ifitisbigenough;otherwise,anewarrayofthe
*sameruntimetypeisallocatedforthispurpose
*@returnanarraycontainingalloftheelementsinthisdeque
*@throwsArrayStoreExceptioniftheruntimetypeofthespecifiedarray
*isnotasupertypeoftheruntimetypeofeveryelementin
*thisdeque
*@throwsNullPointerExceptionifthespecifiedarrayisnull
*/
@Override
@SuppressWarnings(“unchecked”)
publicT[]toArray(T[]a){
finalReentrantLocklock=this.lock;
lock.lock();
try{
if(a.lengthp=first;p!=null;p=p.next){
a[k++]=(T)p.item;
}
if(a.length>k){
a[k]=null;
}
returna;
}finally{
lock.unlock();
}
}

@Override
publicStringtoString(){
finalReentrantLocklock=this.lock;
lock.lock();
try{
Nodep=first;
if(p==null){
return”[]”;
}
StringBuildersb=newStringBuilder();
sb.append(‘[‘);
for(;;){
Ee=p.item;
sb.append(e==this?”(thisCollection)”:e);
p=p.next;
if(p==null){
returnsb.append(‘]’).toString();
}
sb.append(‘,’).append(”);
}
}finally{
lock.unlock();
}
}

/**
*Atomicallyremovesalloftheelementsfromthisdeque.
*Thedequewillbeemptyafterthiscallreturns.
*/
@Override
publicvoidclear(){
finalReentrantLocklock=this.lock;
lock.lock();
try{
for(Nodef=first;f!=null;){
f.item=null;
Noden=f.next;
f.prev=null;
f.next=null;
f=n;
}
first=last=null;
count=0;
notFull.signalAll();
}finally{
lock.unlock();
}
}

/**
*Returnsaniteratorovertheelementsinthisdequeinpropersequence.
*Theelementswillbereturnedinorderfromfirst(head)tolast(tail).
*
*

Thereturnediteratoris
*weaklyconsistent.
*
*@returnaniteratorovertheelementsinthisdequeinpropersequence
*/
@Override
publicIteratoriterator(){
returnnewItr();
}

/**
*Returnsaniteratorovertheelementsinthisdequeinreverse
*sequentialorder.Theelementswillbereturnedinorderfrom
*last(tail)tofirst(head).
*
*

Thereturnediteratoris
*weaklyconsistent.
*
*@returnaniteratorovertheelementsinthisdequeinreverseorder
*/
@Override
publicIteratordescendingIterator(){
returnnewDescendingItr();
}

/**
*BaseclassforIteratorsforResizableCapacityLinkedBlockIngQueue
*/
privateabstractclassAbstractItrimplementsIterator{
/**
*Thenextnodetoreturninnext()
*/
Nodenext;

/**
*nextItemholdsontoitemfieldsbecauseonceweclaimthat
*anelementexistsinhasNext(),wemustreturnitemread
*underlock(inadvance())evenifitwasintheprocessof
*beingremovedwhenhasNext()wascalled.
*/
EnextItem;

/**
*Nodereturnedbymostrecentcalltonext.Neededbyremove.
*Resettonullifthiselementisdeletedbyacalltoremove.
*/
privateNodelastRet;

abstractNodefirstNode();

abstractNodenextNode(Noden);

AbstractItr(){
//settoinitialposition
finalReentrantLocklock=ResizableCapacityLinkedBlockingQueue.this.lock;
lock.lock();
try{
next=firstNode();
nextItem=(next==null)?null:next.item;
}finally{
lock.unlock();
}
}

/**
*Returnsthesuccessornodeofthegivennon-null,but
*possiblypreviouslydeleted,node.
*/
privateNodesucc(Noden){
//Chainsofdeletednodesendinginnullorself-links
//arepossibleifmultipleinteriornodesareremoved.
for(;;){
Nodes=nextNode(n);
if(s==null){
returnnull;
}elseif(s.item!=null){
returns;
}elseif(s==n){
returnfirstNode();
}else{
n=s;
}
}
}

/**
*Advancesnext.
*/
voidadvance(){
finalReentrantLocklock=ResizableCapacityLinkedBlockingQueue.this.lock;
lock.lock();
try{
//assertnext!=null;
next=succ(next);
nextItem=(next==null)?null:next.item;
}finally{
lock.unlock();
}
}

@Override
publicbooleanhasNext(){
returnnext!=null;
}

@Override
publicEnext(){
if(next==null){
thrownewNoSuchElementException();
}
lastRet=next;
Ex=nextItem;
advance();
returnx;
}

@Override
publicvoidremove(){
Noden=lastRet;
if(n==null){
thrownewIllegalStateException();
}
lastRet=null;
finalReentrantLocklock=ResizableCapacityLinkedBlockingQueue.this.lock;
lock.lock();
try{
if(n.item!=null){
unlink(n);
}
}finally{
lock.unlock();
}
}
}

/**
*Forwarditerator
*/
privateclassItrextendsAbstractItr{
@Override
NodefirstNode(){
returnfirst;
}

@Override
NodenextNode(Noden){
returnn.next;
}
}

/**
*Descendingiterator
*/
privateclassDescendingItrextendsAbstractItr{
@Override
NodefirstNode(){
returnlast;
}

@Override
NodenextNode(Noden){
returnn.prev;
}
}

/**
*AcustomizedvariantofSpliterators.IteratorSpliterator
*/
staticfinalclassLBDSpliteratorimplementsSpliterator{
staticfinalintMAX_BATCH=1queue;
Nodecurrent;//currentnode;nulluntilinitialized
intbatch;//batchsizeforsplits
booleanexhausted;//truewhennomorenodes
longest;//sizeestimate

LBDSpliterator(ResizableCapacityLinkedBlockingQueuequeue){
this.queue=queue;
this.est=queue.size();
}

@Override
publiclongestimateSize(){
returnest;
}

@Override
publicSpliteratortrySplit(){
Nodeh;
finalResizableCapacityLinkedBlockingQueueq=this.queue;
intb=batch;
intn=(b=MAX_BATCH)?MAX_BATCH:b+1;
if(!exhausted&&
((h=current)!=null||(h=q.first)!=null)&&
h.next!=null){
Object[]a=newObject[n];
finalReentrantLocklock=q.lock;
inti=0;
Nodep=current;
lock.lock();
try{
if(p!=null||(p=q.first)!=null){
do{
if((a[i]=p.item)!=null){
++i;
}
}while((p=p.next)!=null&&i0){
batch=i;
returnSpliterators.spliterator
(a,0,i,Spliterator.ORDERED|Spliterator.NONNULL|
Spliterator.CONCURRENT);
}
}
returnnull;
}

@Override
publicvoidforEachRemaining(ConsumersuperE>action){
if(action==null){
thrownewNullPointerException();
}
finalResizableCapacityLinkedBlockingQueueq=this.queue;
finalReentrantLocklock=q.lock;
if(!exhausted){
exhausted=true;
Nodep=current;
do{
Ee=null;
lock.lock();
try{
if(p==null){
p=q.first;
}
while(p!=null){
e=p.item;
p=p.next;
if(e!=null){
break;
}
}
}finally{
lock.unlock();
}
if(e!=null){
action.accept(e);
}
}while(p!=null);
}
}

@Override
publicbooleantryAdvance(ConsumersuperE>action){
if(action==null){
thrownewNullPointerException();
}
finalResizableCapacityLinkedBlockingQueueq=this.queue;
finalReentrantLocklock=q.lock;
if(!exhausted){
Ee=null;
lock.lock();
try{
if(current==null){
current=q.first;
}
while(current!=null){
e=current.item;
current=current.next;
if(e!=null){
break;
}
}
}finally{
lock.unlock();
}
if(current==null){
exhausted=true;
}
if(e!=null){
action.accept(e);
returntrue;
}
}
returnfalse;
}

@Override
publicintcharacteristics(){
returnSpliterator.ORDERED|Spliterator.NONNULL|
Spliterator.CONCURRENT;
}
}

/**
*Returnsa{@linkSpliterator}overtheelementsinthisdeque.
*
*

Thereturnedspliteratoris
*weaklyconsistent.
*
*

The{@codeSpliterator}reports{@linkSpliterator#CONCURRENT},
*{@linkSpliterator#ORDERED},and{@linkSpliterator#NONNULL}.
*
*@returna{@codeSpliterator}overtheelementsinthisdeque
*@implNoteThe{@codeSpliterator}implements{@codetrySplit}topermitlimited
*parallelism.
*@since1.8
*/
@Override
publicSpliteratorspliterator(){
returnnewLBDSpliterator(this);
}

/**
*Savesthisdequetoastream(thatis,serializesit).
*
*@paramsthestream
*@throwsjava.io.IOExceptionifanI/Oerroroccurs
*@serialDataThecapacity(int),followedbyelements(eachan
*{@codeObject})intheproperorder,followedbyanull
*/
privatevoidwriteObject(java.io.ObjectOutputStreams)
throwsjava.io.IOException{
finalReentrantLocklock=this.lock;
lock.lock();
try{
//Writeoutcapacityandanyhiddenstuff
s.defaultWriteObject();
//Writeoutallelementsintheproperorder.
for(Nodep=first;p!=null;p=p.next){
s.writeObject(p.item);
}
//Usetrailingnullassentinel
s.writeObject(null);
}finally{
lock.unlock();
}
}

/**
*Reconstitutesthisdequefromastream(thatis,deserializesit).
*
*@paramsthestream
*@throwsClassNotFoundExceptioniftheclassofaserializedobject
*couldnotbefound
*@throwsjava.io.IOExceptionifanI/Oerroroccurs
*/
privatevoidreadObject(java.io.ObjectInputStreams)
throwsjava.io.IOException,ClassNotFoundException{
s.defaultReadObject();
count=0;
first=null;
last=null;
//Readinallelementsandplaceinqueue
for(;;){
@SuppressWarnings(“unchecked”)
Eitem=(E)s.readObject();
if(item==null){
break;
}
add(item);
}
}
}

Thereturnedarraywillbe”safe”inthatnoreferencestoitare
*maintainedbythisdeque.(Inotherwords,thismethodmustallocate
*anewarray).Thecalleristhusfreetomodifythereturnedarray.
*
*Thismethodactsasbridgebetweenarray-basedandcollection-based
*APIs.
*
*@returnanarraycontainingalloftheelementsinthisdeque
*/
@Override
@SuppressWarnings(“unchecked”)
publicObject[]toArray(){
finalReentrantLocklock=this.lock;
lock.lock();
try{
Object[]a=newObject[count];
intk=0;
for(Nodep=first;p!=null;p=p.next){
a[k++]=p.item;
}
returna;
}finally{
lock.unlock();
}
}

/**
*Returnsanarraycontainingalloftheelementsinthisdeque,in
*propersequence;theruntimetypeofthereturnedarrayisthatof
*thespecifiedarray.Ifthedequefitsinthespecifiedarray,it
*isreturnedtherein.Otherwise,anewarrayisallocatedwiththe
*runtimetypeofthespecifiedarrayandthesizeofthisdeque.
*
*

Ifthisdequefitsinthespecifiedarraywithroomtospare
*(i.e.,thearrayhasmoreelementsthanthisdeque),theelementin
*thearrayimmediatelyfollowingtheendofthedequeissetto
*{@codenull}.
*
*

Likethe{@link#toArray()}method,thismethodactsasbridgebetween
*array-basedandcollection-basedAPIs.Further,thismethodallows
*precisecontrolovertheruntimetypeoftheoutputarray,andmay,
*undercertaincircumstances,beusedtosaveallocationcosts.
*
*

Suppose{@codex}isadequeknowntocontainonlystrings.
*Thefollowingcodecanbeusedtodumpthedequeintoanewly
*allocatedarrayof{@codeString}:
*
*

{@codeString[]y=x.toArray(newString[0]);}

*

*Notethat{@codetoArray(newObject[0])}isidenticalinfunctionto
*{@codetoArray()}.
*
*@paramathearrayintowhichtheelementsofthedequeareto
*bestored,ifitisbigenough;otherwise,anewarrayofthe
*sameruntimetypeisallocatedforthispurpose
*@returnanarraycontainingalloftheelementsinthisdeque
*@throwsArrayStoreExceptioniftheruntimetypeofthespecifiedarray
*isnotasupertypeoftheruntimetypeofeveryelementin
*thisdeque
*@throwsNullPointerExceptionifthespecifiedarrayisnull
*/
@Override
@SuppressWarnings(“unchecked”)
publicT[]toArray(T[]a){
finalReentrantLocklock=this.lock;
lock.lock();
try{
if(a.lengthp=first;p!=null;p=p.next){
a[k++]=(T)p.item;
}
if(a.length>k){
a[k]=null;
}
returna;
}finally{
lock.unlock();
}
}

@Override
publicStringtoString(){
finalReentrantLocklock=this.lock;
lock.lock();
try{
Nodep=first;
if(p==null){
return”[]”;
}
StringBuildersb=newStringBuilder();
sb.append(‘[‘);
for(;;){
Ee=p.item;
sb.append(e==this?”(thisCollection)”:e);
p=p.next;
if(p==null){
returnsb.append(‘]’).toString();
}
sb.append(‘,’).append(”);
}
}finally{
lock.unlock();
}
}

/**
*Atomicallyremovesalloftheelementsfromthisdeque.
*Thedequewillbeemptyafterthiscallreturns.
*/
@Override
publicvoidclear(){
finalReentrantLocklock=this.lock;
lock.lock();
try{
for(Nodef=first;f!=null;){
f.item=null;
Noden=f.next;
f.prev=null;
f.next=null;
f=n;
}
first=last=null;
count=0;
notFull.signalAll();
}finally{
lock.unlock();
}
}

/**
*Returnsaniteratorovertheelementsinthisdequeinpropersequence.
*Theelementswillbereturnedinorderfromfirst(head)tolast(tail).
*
*

Thereturnediteratoris
*weaklyconsistent.
*
*@returnaniteratorovertheelementsinthisdequeinpropersequence
*/
@Override
publicIteratoriterator(){
returnnewItr();
}

/**
*Returnsaniteratorovertheelementsinthisdequeinreverse
*sequentialorder.Theelementswillbereturnedinorderfrom
*last(tail)tofirst(head).
*
*

Thereturnediteratoris
*weaklyconsistent.
*
*@returnaniteratorovertheelementsinthisdequeinreverseorder
*/
@Override
publicIteratordescendingIterator(){
returnnewDescendingItr();
}

/**
*BaseclassforIteratorsforResizableCapacityLinkedBlockIngQueue
*/
privateabstractclassAbstractItrimplementsIterator{
/**
*Thenextnodetoreturninnext()
*/
Nodenext;

/**
*nextItemholdsontoitemfieldsbecauseonceweclaimthat
*anelementexistsinhasNext(),wemustreturnitemread
*underlock(inadvance())evenifitwasintheprocessof
*beingremovedwhenhasNext()wascalled.
*/
EnextItem;

/**
*Nodereturnedbymostrecentcalltonext.Neededbyremove.
*Resettonullifthiselementisdeletedbyacalltoremove.
*/
privateNodelastRet;

abstractNodefirstNode();

abstractNodenextNode(Noden);

AbstractItr(){
//settoinitialposition
finalReentrantLocklock=ResizableCapacityLinkedBlockingQueue.this.lock;
lock.lock();
try{
next=firstNode();
nextItem=(next==null)?null:next.item;
}finally{
lock.unlock();
}
}

/**
*Returnsthesuccessornodeofthegivennon-null,but
*possiblypreviouslydeleted,node.
*/
privateNodesucc(Noden){
//Chainsofdeletednodesendinginnullorself-links
//arepossibleifmultipleinteriornodesareremoved.
for(;;){
Nodes=nextNode(n);
if(s==null){
returnnull;
}elseif(s.item!=null){
returns;
}elseif(s==n){
returnfirstNode();
}else{
n=s;
}
}
}

/**
*Advancesnext.
*/
voidadvance(){
finalReentrantLocklock=ResizableCapacityLinkedBlockingQueue.this.lock;
lock.lock();
try{
//assertnext!=null;
next=succ(next);
nextItem=(next==null)?null:next.item;
}finally{
lock.unlock();
}
}

@Override
publicbooleanhasNext(){
returnnext!=null;
}

@Override
publicEnext(){
if(next==null){
thrownewNoSuchElementException();
}
lastRet=next;
Ex=nextItem;
adva免费云主机域名nce();
returnx;
}

@Override
publicvoidremove(){
Noden=lastRet;
if(n==null){
thrownewIllegalStateException();
}
lastRet=null;
finalReentrantLocklock=ResizableCapacityLinkedBlockingQueue.this.lock;
lock.lock();
try{
if(n.item!=null){
unlink(n);
}
}finally{
lock.unlock();
}
}
}

/**
*Forwarditerator
*/
privateclassItrextendsAbstractItr{
@Override
NodefirstNode(){
returnfirst;
}

@Override
NodenextNode(Noden){
returnn.next;
}
}

/**
*Descendingiterator
*/
privateclassDescendingItrextendsAbstractItr{
@Override
NodefirstNode(){
returnlast;
}

@Override
NodenextNode(Noden){
returnn.prev;
}
}

/**
*AcustomizedvariantofSpliterators.IteratorSpliterator
*/
staticfinalclassLBDSpliteratorimplementsSpliterator{
staticfinalintMAX_BATCH=1queue;
Nodecurrent;//currentnode;nulluntilinitialized
intbatch;//batchsizeforsplits
booleanexhausted;//truewhennomorenodes
longest;//sizeestimate

LBDSpliterator(ResizableCapacityLinkedBlockingQueuequeue){
this.queue=queue;
this.est=queue.size();
}

@Override
publiclongestimateSize(){
returnest;
}

@Override
publicSpliteratortrySplit(){
Nodeh;
finalResizableCapacityLinkedBlockingQueueq=this.queue;
intb=batch;
intn=(b=MAX_BATCH)?MAX_BATCH:b+1;
if(!exhausted&&
((h=current)!=null||(h=q.first)!=null)&&
h.next!=null){
Object[]a=newObject[n];
finalReentrantLocklock=q.lock;
inti=0;
Nodep=current;
lock.lock();
try{
if(p!=null||(p=q.first)!=null){
do{
if((a[i]=p.item)!=null){
++i;
}
}while((p=p.next)!=null&&i0){
batch=i;
returnSpliterators.spliterator
(a,0,i,Spliterator.ORDERED|Spliterator.NONNULL|
Spliterator.CONCURRENT);
}
}
returnnull;
}

@Override
publicvoidforEachRemaining(ConsumersuperE>action){
if(action==null){
thrownewNullPointerException();
}
finalResizableCapacityLinkedBlockingQueueq=this.queue;
finalReentrantLocklock=q.lock;
if(!exhausted){
exhausted=true;
Nodep=current;
do{
Ee=null;
lock.lock();
try{
if(p==null){
p=q.first;
}
while(p!=null){
e=p.item;
p=p.next;
if(e!=null){
break;
}
}
}finally{
lock.unlock();
}
if(e!=null){
action.accept(e);
}
}while(p!=null);
}
}

@Override
publicbooleantryAdvance(ConsumersuperE>action){
if(action==null){
thrownewNullPointerException();
}
finalResizableCapacityLinkedBlockingQueueq=this.queue;
finalReentrantLocklock=q.lock;
if(!exhausted){
Ee=null;
lock.lock();
try{
if(current==null){
current=q.first;
}
while(current!=null){
e=current.item;
current=current.next;
if(e!=null){
break;
}
}
}finally{
lock.unlock();
}
if(current==null){
exhausted=true;
}
if(e!=null){
action.accept(e);
returntrue;
}
}
returnfalse;
}

@Override
publicintcharacteristics(){
returnSpliterator.ORDERED|Spliterator.NONNULL|
Spliterator.CONCURRENT;
}
}

/**
*Returnsa{@linkSpliterator}overtheelementsinthisdeque.
*
*

Thereturnedspliteratoris
*weaklyconsistent.
*
*

The{@codeSpliterator}reports{@linkSpliterator#CONCURRENT},
*{@linkSpliterator#ORDERED},and{@linkSpliterator#NONNULL}.
*
*@returna{@codeSpliterator}overtheelementsinthisdeque
*@implNoteThe{@codeSpliterator}implements{@codetrySplit}topermitlimited
*parallelism.
*@since1.8
*/
@Override
publicSpliteratorspliterator(){
returnnewLBDSpliterator(this);
}

/**
*Savesthisdequetoastream(thatis,serializesit).
*
*@paramsthestream
*@throwsjava.io.IOExceptionifanI/Oerroroccurs
*@serialDataThecapacity(int),followedbyelements(eachan
*{@codeObject})intheproperorder,followedbyanull
*/
privatevoidwriteObject(java.io.ObjectOutputStreams)
throwsjava.io.IOException{
finalReentrantLocklock=this.lock;
lock.lock();
try{
//Writeoutcapacityandanyhiddenstuff
s.defaultWriteObject();
//Writeoutallelementsintheproperorder.
for(Nodep=first;p!=null;p=p.next){
s.writeObject(p.item);
}
//Usetrailingnullassentinel
s.writeObject(null);
}finally{
lock.unlock();
}
}

/**
*Reconstitutesthisdequefromastream(thatis,deserializesit).
*
*@paramsthestream
*@throwsClassNotFoundExceptioniftheclassofaserializedobject
*couldnotbefound
*@throwsjava.io.IOExceptionifanI/Oerroroccurs
*/
privatevoidreadObject(java.io.ObjectInputStreams)
throwsjava.io.IOException,ClassNotFoundException{
s.defaultReadObject();
count=0;
first=null;
last=null;
//Readinallelementsandplaceinqueue
for(;;){
@SuppressWarnings(“unchecked”)
Eitem=(E)s.readObject();
if(item==null){
break;
}
add(item);
}
}
}

Ifthisdequefitsinthespecifiedarraywithroomtospare
*(i.e.,thearrayhasmoreelementsthanthisdeque),theelementin
*thearrayimmediatelyfollowingtheendofthedequeissetto
*{@codenull}.
*
*Likethe{@link#toArray()}method,thismethodactsasbridgebetween
*array-basedandcollection-basedAPIs.Further,thismethodallows
*precisecontrolovertheruntimetypeoftheoutputarray,andmay,
*undercertaincircumstances,beusedtosaveallocationcosts.
*
*Suppose{@codex}isadequeknowntocontainonlystrings.
*Thefollowingcodecanbeusedtodumpthedequeintoanewly
*allocatedarrayof{@codeString}:
*
*
*Notethat{@codetoArray(newObject[0])}isidenticalinfunctionto
*{@codetoArray()}.
*
*@paramathearrayintowhichtheelementsofthedequeareto
*bestored,ifitisbigenough;otherwise,anewarrayofthe
*sameruntimetypeisallocatedforthispurpose
*@returnanarraycontainingalloftheelementsinthisdeque
*@throwsArrayStoreExceptioniftheruntimetypeofthespecifiedarray
*isnotasupertypeoftheruntimetypeofeveryelementin
*thisdeque
*@throwsNullPointerExceptionifthespecifiedarrayisnull
*/
@Override
@SuppressWarnings(“unchecked”)
publicT[]toArray(T[]a){
finalReentrantLocklock=this.lock;
lock.lock();
try{
if(a.lengthp=first;p!=null;p=p.next){
a[k++]=(T)p.item;
}
if(a.length>k){
a[k]=null;
}
returna;
}finally{
lock.unlock();
}
}

@Override
publicStringtoString(){
finalReentrantLocklock=this.lock;
lock.lock();
try{
Nodep=first;
if(p==null){
return”[]”;
}
StringBuildersb=newStringBuilder();
sb.append(‘[‘);
for(;;){
Ee=p.item;
sb.append(e==this?”(thisCollection)”:e);
p=p.next;
if(p==null){
returnsb.append(‘]’).toString();
}
sb.append(‘,’).append(”);
}
}finally{
lock.unlock();
}
}

/**
*Atomicallyremovesalloftheelementsfromthisdeque.
*Thedequewillbeemptyafterthiscallreturns.
*/
@Override
publicvoidclear(){
finalReentrantLocklock=this.lock;
lock.lock();
try{
for(Nodef=first;f!=null;){
f.item=null;
Noden=f.next;
f.prev=null;
f.next=null;
f=n;
}
first=last=null;
count=0;
notFull.signalAll();
}finally{
lock.unlock();
}
}

/**
*Returnsaniteratorovertheelementsinthisdequeinpropersequence.
*Theelementswillbereturnedinorderfromfirst(head)tolast(tail).
*
*

Thereturnediteratoris
*weaklyconsistent.
*
*@returnaniteratorovertheelementsinthisdequeinpropersequence
*/
@Override
publicIteratoriterator(){
returnnewItr();
}

/**
*Returnsaniteratorovertheelementsinthisdequeinreverse
*sequentialorder.Theelementswillbereturnedinorderfrom
*last(tail)tofirst(head).
*
*

Thereturnediteratoris
*weaklyconsistent.
*
*@returnaniteratorovertheelementsinthisdequeinreverseorder
*/
@Override
publicIteratordescendingIterator(){
returnnewDescendingItr();
}

/**
*BaseclassforIteratorsforResizableCapacityLinkedBlockIngQueue
*/
privateabstractclassAbstractItrimplementsIterator{
/**
*Thenextnodetoreturninnext()
*/
Nodenext;

/**
*nextItemholdsontoitemfieldsbecauseonceweclaimthat
*anelementexistsinhasNext(),wemustreturnitemread
*underlock(inadvance())evenifitwasintheprocessof
*beingremovedwhenhasNext()wascalled.
*/
EnextItem;

/**
*Nodereturnedbymostrecentcalltonext.Neededbyremove.
*Resettonullifthiselementisdeletedbyacalltoremove.
*/
privateNodelastRet;

abstractNodefirstNode();

abstractNodenextNode(Noden);

AbstractItr(){
//settoinitialposition
finalReentrantLocklock=ResizableCapacityLinkedBlockingQueue.this.lock;
lock.lock();
try{
next=firstNode();
nextItem=(next==null)?null:next.item;
}finally{
lock.unlock();
}
}

/**
*Returnsthesuccessornodeofthegivennon-null,but
*possiblypreviouslydeleted,node.
*/
privateNodesucc(Noden){
//Chainsofdeletednodesendinginnullorself-links
//arepossibleifmultipleinteriornodesareremoved.
for(;;){
Nodes=nextNode(n);
if(s==null){
returnnull;
}elseif(s.item!=null){
returns;
}elseif(s==n){
returnfirstNode();
}else{
n=s;
}
}
}

/**
*Advancesnext.
*/
voidadvance(){
finalReentrantLocklock=ResizableCapacityLinkedBlockingQueue.this.lock;
lock.lock();
try{
//assertnext!=null;
next=succ(next);
nextItem=(next==null)?null:next.item;
}finally{
lock.unlock();
}
}

@Override
publicbooleanhasNext(){
returnnext!=null;
}

@Override
publicEnext(){
if(next==null){
thrownewNoSuchElementException();
}
lastRet=next;
Ex=nextItem;
advance();
returnx;
}

@Override
publicvoidremove(){
Noden=lastRet;
if(n==null){
thrownewIllegalStateException();
}
lastRet=null;
finalReentrantLocklock=ResizableCapacityLinkedBlockingQueue.this.lock;
lock.lock();
try{
if(n.item!=null){
unlink(n);
}
}finally{
lock.unlock();
}
}
}

/**
*Forwarditerator
*/
privateclassItrextendsAbstractItr{
@Override
NodefirstNode(){
returnfirst;
}

@Override
NodenextNode(Noden){
returnn.next;
}
}

/**
*Descendingiterator
*/
privateclassDescendingItrextendsAbstractItr{
@Override
NodefirstNode(){
returnlast;
}

@Override
NodenextNode(Noden){
returnn.prev;
}
}

/**
*AcustomizedvariantofSpliterators.IteratorSpliterator
*/
staticfinalclassLBDSpliteratorimplementsSpliterator{
staticfinalintMAX_BATCH=1queue;
Nodecurrent;//currentnode;nulluntilinitialized
intbatch;//batchsizeforsplits
booleanexhausted;//truewhennomorenodes
longest;//sizeestimate

LBDSpliterator(ResizableCapacityLinkedBlockingQueuequeue){
this.queue=queue;
this.est=queue.size();
}

@Override
publiclongestimateSize(){
returnest;
}

@Override
publicSpliteratortrySplit(){
Nodeh;
finalResizableCapacityLinkedBlockingQueueq=this.queue;
intb=batch;
intn=(b=MAX_BATCH)?MAX_BATCH:b+1;
if(!exhausted&&
((h=current)!=null||(h=q.first)!=null)&&
h.next!=null){
Object[]a=newObject[n];
finalReentrantLocklock=q.lock;
inti=0;
Nodep=current;
lock.lock();
try{
if(p!=null||(p=q.first)!=null){
do{
if((a[i]=p.item)!=null){
++i;
}
}while((p=p.next)!=null&&i0){
batch=i;
returnSpliterators.spliterator
(a,0,i,Spliterator.ORDERED|Spliterator.NONNULL|
Spliterator.CONCURRENT);
}
}
returnnull;
}

@Override
publicvoidforEachRemaining(ConsumersuperE>action){
if(action==null){
thrownewNullPointerException();
}
finalResizableCapacityLinkedBlockingQueueq=this.queue;
finalReentrantLocklock=q.lock;
if(!exhausted){
exhausted=true;
Nodep=current;
do{
Ee=null;
lock.lock();
try{
if(p==null){
p=q.first;
}
while(p!=null){
e=p.item;
p=p.next;
if(e!=null){
break;
}
}
}finally{
lock.unlock();
}
if(e!=null){
action.accept(e);
}
}while(p!=null);
}
}

@Override
publicbooleantryAdvance(ConsumersuperE>action){
if(action==null){
thrownewNullPointerException();
}
finalResizableCapacityLinkedBlockingQueueq=this.queue;
finalReentrantLocklock=q.lock;
if(!exhausted){
Ee=null;
lock.lock();
try{
if(current==null){
current=q.first;
}
while(current!=null){
e=current.item;
current=current.next;
if(e!=null){
break;
}
}
}finally{
lock.unlock();
}
if(current==null){
exhausted=true;
}
if(e!=null){
action.accept(e);
returntrue;
}
}
returnfalse;
}

@Override
publicintcharacteristics(){
returnSpliterator.ORDERED|Spliterator.NONNULL|
Spliterator.CONCURRENT;
}
}

/**
*Returnsa{@linkSpliterator}overtheelementsinthisdeque.
*
*

Thereturnedspliteratoris
*weaklyconsistent.
*
*

The{@codeSpliterator}reports{@linkSpliterator#CONCURRENT},
*{@linkSpliterator#ORDERED},and{@linkSpliterator#NONNULL}.
*
*@returna{@codeSpliterator}overtheelementsinthisdeque
*@implNoteThe{@codeSpliterator}implements{@codetrySplit}topermitlimited
*parallelism.
*@since1.8
*/
@Override
publicSpliteratorspliterator(){
returnnewLBDSpliterator(this);
}

/**
*Savesthisdequetoastream(thatis,serializesit).
*
*@paramsthestream
*@throwsjava.io.IOExceptionifanI/Oerroroccurs
*@serialDataThecapacity(int),followedbyelements(eachan
*{@codeObject})intheproperorder,followedbyanull
*/
privatevoidwriteObject(java.io.ObjectOutputStreams)
throwsjava.io.IOException{
finalReentrantLocklock=this.lock;
lock.lock();
try{
//Writeoutcapacityandanyhiddenstuff
s.defaultWriteObject();
//Writeoutallelementsintheproperorder.
for(Nodep=first;p!=null;p=p.next){
s.writeObject(p.item);
}
//Usetrailingnullassentinel
s.writeObject(null);
}finally{
lock.unlock();
}
}

/**
*Reconstitutesthisdequefromastream(thatis,deserializesit).
*
*@paramsthestream
*@throwsClassNotFoundExceptioniftheclassofaserializedobject
*couldnotbefound
*@throwsjava.io.IOExceptionifanI/Oerroroccurs
*/
privatevoidreadObject(java.io.ObjectInputStreams)
throwsjava.io.IOException,ClassNotFoundException{
s.defaultReadObject();
count=0;
first=null;
last=null;
//Readinallelementsandplaceinqueue
for(;;){
@SuppressWarnings(“unchecked”)
Eitem=(E)s.readObject();
if(item==null){
break;
}
add(item);
}
}
}

Thereturnediteratoris
*weaklyconsistent.
*
*@returnaniteratorovertheelementsinthisdequeinpropersequence
*/
@Override
publicIteratoriterator(){
returnnewItr();
}

/**
*Returnsaniteratorovertheelementsinthisdequeinreverse
*sequentialorder.Theelementswillbereturnedinorderfrom
*last(tail)tofirst(head).
*
*

Thereturnediteratoris
*weaklyconsistent.
*
*@returnaniteratorovertheelementsinthisdequeinreverseorder
*/
@Override
publicIteratordescendingIterator(){
returnnewDescendingItr();
}

/**
*BaseclassforIteratorsforResizableCapacityLinkedBlockIngQueue
*/
privateabstractclassAbstractItrimplementsIterator{
/**
*Thenextnodetoreturninnext()
*/
Nodenext;

/**
*nextItemholdsontoitemfieldsbecauseonceweclaimthat
*anelementexistsinhasNext(),wemustreturnitemread
*underlock(inadvance())evenifitwasintheprocessof
*beingremovedwhenhasNext()wascalled.
*/
EnextItem;

/**
*Nodereturnedbymostrecentcalltonext.Neededbyremove.
*Resettonullifthiselementisdeletedbyacalltoremove.
*/
privateNodelastRet;

abstractNodefirstNode();

abstractNodenextNode(Noden);

AbstractItr(){
//settoinitialposition
finalReentrantLocklock=ResizableCapacityLinkedBlockingQueue.this.lock;
lock.lock();
try{
next=firstNode();
nextItem=(next==null)?null:next.item;
}finally{
lock.unlock();
}
}

/**
*Returnsthesuccessornodeofthegivennon-null,but
*possiblypreviouslydeleted,node.
*/
privateNodesucc(Noden){
//Chainsofdeletednodesendinginnullorself-links
//arepossibleifmultipleinteriornodesareremoved.
for(;;){
Nodes=nextNode(n);
if(s==null){
returnnull;
}elseif(s.item!=null){
returns;
}elseif(s==n){
returnfirstNode();
}else{
n=s;
}
}
}

/**
*Advancesnext.
*/
voidadvance(){
finalReentrantLocklock=ResizableCapacityLinkedBlockingQueue.this.lock;
lock.lock();
try{
//assertnext!=null;
next=succ(next);
nextItem=(next==null)?null:next.item;
}finally{
lock.unlock();
}
}

@Override
publicbooleanhasNext(){
returnnext!=null;
}

@Override
publicEnext(){
if(next==null){
thrownewNoSuchElementException();
}
lastRet=next;
Ex=nextItem;
advance();
returnx;
}

@Override
publicvoidremove(){
Noden=lastRet;
if(n==null){
thrownewIllegalStateException();
}
lastRet=null;
finalReentrantLocklock=ResizableCapacityLinkedBlockingQueue.this.lock;
lock.lock();
try{
if(n.item!=null){
unlink(n);
}
}finally{
lock.unlock();
}
}
}

/**
*Forwarditerator
*/
privateclassItrextendsAbstractItr{
@Override
NodefirstNode(){
returnfirst;
}

@Override
NodenextNode(Noden){
returnn.next;
}
}

/**
*Descendingiterator
*/
privateclassDescendingItrextendsAbstractItr{
@Override
NodefirstNode(){
returnlast;
}

@Override
NodenextNode(Noden){
returnn.prev;
}
}

/**
*AcustomizedvariantofSpliterators.IteratorSpliterator
*/
staticfinalclassLBDSpliteratorimplementsSpliterator{
staticfinalintMAX_BATCH=1queue;
Nodecurrent;//currentnode;nulluntilinitialized
intbatch;//batchsizeforsplits
booleanexhausted;//truewhennomorenodes
longest;//sizeestimate

LBDSpliterator(ResizableCapacityLinkedBlockingQueuequeue){
this.queue=queue;
this.est=queue.size();
}

@Override
publiclongestimateSize(){
returnest;
}

@Override
publicSpliteratortrySplit(){
Nodeh;
finalResizableCapacityLinkedBlockingQueueq=this.queue;
intb=batch;
intn=(b=MAX_BATCH)?MAX_BATCH:b+1;
if(!exhausted&&
((h=current)!=null||(h=q.first)!=null)&&
h.next!=null){
Object[]a=newObject[n];
finalReentrantLocklock=q.lock;
inti=0;
Nodep=current;
lock.lock();
try{
if(p!=null||(p=q.first)!=null){
do{
if((a[i]=p.item)!=null){
++i;
}
}while((p=p.next)!=null&&i0){
batch=i;
returnSpliterators.spliterator
(a,0,i,Spliterator.ORDERED|Spliterator.NONNULL|
Spliterator.CONCURRENT);
}
}
returnnull;
}

@Override
publicvoidforEachRemaining(ConsumersuperE>action){
if(action==null){
thrownewNullPointerException();
}
finalResizableCapacityLinkedBlockingQueueq=this.queue;
finalReentrantLocklock=q.lock;
if(!exhausted){
exhausted=true;
Nodep=current;
do{
Ee=null;
lock.lock();
try{
if(p==null){
p=q.first;
}
while(p!=null){
e=p.item;
p=p.next;
if(e!=null){
break;
}
}
}finally{
lock.unlock();
}
if(e!=null){
action.accept(e);
}
}while(p!=null);
}
}

@Override
publicbooleantryAdvance(ConsumersuperE>action){
if(action==null){
thrownewNullPointerException();
}
finalResizableCapacityLinkedBlockingQueueq=this.queue;
finalReentrantLocklock=q.lock;
if(!exhausted){
Ee=null;
lock.lock();
try{
if(current==null){
current=q.first;
}
while(current!=null){
e=current.item;
current=current.next;
if(e!=null){
break;
}
}
}finally{
lock.unlock();
}
if(current==null){
exhausted=true;
}
if(e!=null){
action.accept(e);
returntrue;
}
}
returnfalse;
}

@Override
publicintcharacteristics(){
returnSpliterator.ORDERED|Spliterator.NONNULL|
Spliterator.CONCURRENT;
}
}

/**
*Returnsa{@linkSpliterator}overtheelementsinthisdeque.
*
*

Thereturnedspliteratoris
*weaklyconsistent.
*
*

The{@codeSpliterator}reports{@linkSpliterator#CONCURRENT},
*{@linkSpliterator#ORDERED},and{@linkSpliterator#NONNULL}.
*
*@returna{@codeSpliterator}overtheelementsinthisdeque
*@implNoteThe{@codeSpliterator}implements{@codetrySplit}topermitlimited
*parallelism.
*@since1.8
*/
@Override
publicSpliteratorspliterator(){
returnnewLBDSpliterator(this);
}

/**
*Savesthisdequetoastream(thatis,serializesit).
*
*@paramsthestream
*@throwsjava.io.IOExceptionifanI/Oerroroccurs
*@serialDataThecapacity(int),followedbyelements(eachan
*{@codeObject})intheproperorder,followedbyanull
*/
privatevoidwriteObject(java.io.ObjectOutputStreams)
throwsjava.io.IOException{
finalReentrantLocklock=this.lock;
lock.lock();
try{
//Writeoutcapacityandanyhiddenstuff
s.defaultWriteObject();
//Writeoutallelementsintheproperorder.
for(Nodep=first;p!=null;p=p.next){
s.writeObject(p.item);
}
//Usetrailingnullassentinel
s.writeObject(null);
}finally{
lock.unlock();
}
}

/**
*Reconstitutesthisdequefromastream(thatis,deserializesit).
*
*@paramsthestream
*@throwsClassNotFoundExceptioniftheclassofaserializedobject
*couldnotbefound
*@throwsjava.io.IOExceptionifanI/Oerroroccurs
*/
privatevoidreadObject(java.io.ObjectInputStreams)
throwsjava.io.IOException,ClassNotFoundException{
s.defaultReadObject();
count=0;
first=null;
last=null;
//Readinallelementsandplaceinqueue
for(;;){
@SuppressWarnings(“unchecked”)
Eitem=(E)s.readObject();
if(item==null){
break;
}
add(item);
}
}
}

Thereturnediteratoris
*weaklyconsistent.
*
*@returnaniteratorovertheelementsinthisdequeinreverseorder
*/
@Override
publicIteratordescendingIterator(){
returnnewDescendingItr();
}

/**
*BaseclassforIteratorsforResizableCapacityLinkedBlockIngQueue
*/
privateabstractclassAbstractItrimplementsIterator{
/**
*Thenextnodetoreturninnext()
*/
Nodenext;

/**
*nextItemholdsontoitemfieldsbecauseonceweclaimthat
*anelementexistsinhasNext(),wemustreturnitemread
*underlock(inadvance())evenifitwasintheprocessof
*beingremovedwhenhasNext()wascalled.
*/
EnextItem;

/**
*Nodereturnedbymostrecentcalltonext.Neededbyremove.
*Resettonullifthiselementisdeletedbyacalltoremove.
*/
privateNodelastRet;

abstractNodefirstNode();

abstractNodenextNode(Noden);

AbstractItr(){
//settoinitialposition
finalReentrantLocklock=ResizableCapacityLinkedBlockingQueue.this.lock;
lock.lock();
try{
next=firstNode();
nextItem=(next==null)?null:next.item;
}finally{
lock.unlock();
}
}

/**
*Returnsthesuccessornodeofthegivennon-null,but
*possiblypreviouslydeleted,node.
*/
privateNodesucc(Noden){
//Chainsofdeletednodesendinginnullorself-links
//arepossibleifmultipleinteriornodesareremoved.
for(;;){
Nodes=nextNode(n);
if(s==null){
returnnull;
}elseif(s.item!=null){
returns;
}elseif(s==n){
returnfirstNode();
}else{
n=s;
}
}
}

/**
*Advancesnext.
*/
voidadvance(){
finalReentrantLocklock=ResizableCapacityLinkedBlockingQueue.this.lock;
lock.lock();
try{
//assertnext!=null;
next=succ(next);
nextItem=(next==null)?null:next.item;
}finally{
lock.unlock();
}
}

@Override
publicbooleanhasNext(){
returnnext!=null;
}

@Override
publicEnext(){
if(next==null){
thrownewNoSuchElementException();
}
lastRet=next;
Ex=nextItem;
advance();
returnx;
}

@Override
publicvoidremove(){
Noden=lastRet;
if(n==null){
thrownewIllegalStateException();
}
lastRet=null;
finalReentrantLocklock=ResizableCapacityLinkedBlockingQueue.this.lock;
lock.lock();
try{
if(n.item!=null){
unlink(n);
}
}finally{
lock.unlock();
}
}
}

/**
*Forwarditerator
*/
privateclassItrextendsAbstractItr{
@Override
NodefirstNode(){
returnfirst;
}

@Override
NodenextNode(Noden){
returnn.next;
}
}

/**
*Descendingiterator
*/
privateclassDescendingItrextendsAbstractItr{
@Override
NodefirstNode(){
returnlast;
}

@Override
NodenextNode(Noden){
returnn.prev;
}
}

/**
*AcustomizedvariantofSpliterators.IteratorSpliterator
*/
staticfinalclassLBDSpliteratorimplementsSpliterator{
staticfinalintMAX_BATCH=1queue;
Nodecurrent;//currentnode;nulluntilinitialized
intbatch;//batchsizeforsplits
booleanexhausted;//truewhennomorenodes
longest;//sizeestimate

LBDSpliterator(ResizableCapacityLinkedBlockingQueuequeue){
this.queue=queue;
this.est=queue.size();
}

@Override
publiclongestimateSize(){
returnest;
}

@Override
publicSpliteratortrySplit(){
Nodeh;
finalResizableCapacityLinkedBlockingQueueq=this.queue;
intb=batch;
intn=(b=MAX_BATCH)?MAX_BATCH:b+1;
if(!exhausted&&
((h=current)!=null||(h=q.first)!=null)&&
h.next!=null){
Object[]a=newObject[n];
finalReentrantLocklock=q.lock;
inti=0;
Nodep=current;
lock.lock();
try{
if(p!=null||(p=q.first)!=null){
do{
if((a[i]=p.item)!=null){
++i;
}
}while((p=p.next)!=null&&i0){
batch=i;
returnSpliterators.spliterator
(a,0,i,Spliterator.ORDERED|Spliterator.NONNULL|
Spliterator.CONCURRENT);
}
}
returnnull;
}

@Override
publicvoidforEachRemaining(ConsumersuperE>action){
if(action==null){
thrownewNullPointerException();
}
finalResizableCapacityLinkedBlockingQueueq=this.queue;
finalReentrantLocklock=q.lock;
if(!exhausted){
exhausted=true;
Nodep=current;
do{
Ee=null;
lock.lock();
try{
if(p==null){
p=q.first;
}
while(p!=null){
e=p.item;
p=p.next;
if(e!=null){
break;
}
}
}finally{
lock.unlock();
}
if(e!=null){
action.accept(e);
}
}while(p!=null);
}
}

@Override
publicbooleantryAdvance(ConsumersuperE>action){
if(action==null){
thrownewNullPointerException();
}
finalResizableCapacityLinkedBlockingQueueq=this.queue;
finalReentrantLocklock=q.lock;
if(!exhausted){
Ee=null;
lock.lock();
try{
if(current==null){
current=q.first;
}
while(current!=null){
e=current.item;
current=current.next;
if(e!=null){
break;
}
}
}finally{
lock.unlock();
}
if(current==null){
exhausted=true;
}
if(e!=null){
action.accept(e);
returntrue;
}
}
returnfalse;
}

@Override
publicintcharacteristics(){
returnSpliterator.ORDERED|Spliterator.NONNULL|
Spliterator.CONCURRENT;
}
}

/**
*Returnsa{@linkSpliterator}overtheelementsinthisdeque.
*
*

Thereturnedspliteratoris
*weaklyconsistent.
*
*

The{@codeSpliterator}reports{@linkSpliterator#CONCURRENT},
*{@linkSpliterator#ORDERED},and{@linkSpliterator#NONNULL}.
*
*@returna{@codeSpliterator}overtheelementsinthisdeque
*@implNoteThe{@codeSpliterator}implements{@codetrySplit}topermitlimited
*parallelism.
*@since1.8
*/
@Override
publicSpliteratorspliterator(){
returnnewLBDSpliterator(this);
}

/**
*Savesthisdequetoastream(thatis,serializesit).
*
*@paramsthestream
*@throwsjava.io.IOExceptionifanI/Oerroroccurs
*@serialDataThecapacity(int),followedbyelements(eachan
*{@codeObject})intheproperorder,followedbyanull
*/
privatevoidwriteObject(java.io.ObjectOutputStreams)
throwsjava.io.IOException{
finalReentrantLocklock=this.lock;
lock.lock();
try{
//Writeoutcapacityandanyhiddenstuff
s.defaultWriteObject();
//Writeoutallelementsintheproperorder.
for(Nodep=first;p!=null;p=p.next){
s.writeObject(p.item);
}
//Usetrailingnullassentinel
s.writeObject(null);
}finally{
lock.unlock();
}
}

/**
*Reconstitutesthisdequefromastream(thatis,deserializesit).
*
*@paramsthestream
*@throwsClassNotFoundExceptioniftheclassofaserializedobject
*couldnotbefound
*@throwsjava.io.IOExceptionifanI/Oerroroccurs
*/
privatevoidreadObject(java.io.ObjectInputStreams)
throwsjava.io.IOException,ClassNotFoundException{
s.defaultReadObject();
count=0;
first=null;
last=null;
//Readinallelementsandplaceinqueue
for(;;){
@SuppressWarnings(“unchecked”)
Eitem=(E)s.readObject();
if(item==null){
break;
}
add(item);
}
}
}

Thereturnedspliteratoris
*weaklyconsistent.
*
*The{@codeSpliterator}reports{@linkSpliterator#CONCURRENT},
*{@linkSpliterator#ORDERED},and{@linkSpliterator#NONNULL}.
*
*@returna{@codeSpliterator}overtheelementsinthisdeque
*@implNoteThe{@codeSpliterator}implements{@codetrySplit}topermitlimited
*parallelism.
*@since1.8
*/
@Override
publicSpliteratorspliterator(){
returnnewLBDSpliterator(this);
}

/**
*Savesthisdequetoastream(thatis,serializesit).
*
*@paramsthestream
*@throwsjava.io.IOExceptionifanI/Oerroroccurs
*@serialDataThecapacity(int),followedbyelements(eachan
*{@codeObject})intheproperorder,followedbyanull
*/
privatevoidwriteObject(java.io.ObjectOutputStreams)
throwsjava.io.IOException{
finalReentrantLocklock=this.lock;
lock.lock();
try{
//Writeoutcapacityandanyhiddenstuff
s.defaultWriteObject();
//Writeoutallelementsintheproperorder.
for(Nodep=first;p!=null;p=p.next){
s.writeObject(p.item);
}
//Usetrailingnullassentinel
s.writeObject(null);
}finally{
lock.unlock();
}
}

/**
*Reconstitutesthisdequefromastream(thatis,deserializesit).
*
*@paramsthestream
*@throwsClassNotFoundExceptioniftheclassofaserializedobject
*couldnotbefound
*@throwsjava.io.IOExceptionifanI/Oerroroccurs
*/
privatevoidreadObject(java.io.ObjectInputStreams)
throwsjava.io.IOException,ClassNotFoundException{
s.defaultReadObject();
count=0;
first=null;
last=null;
//Readinallelementsandplaceinqueue
for(;;){
@SuppressWarnings(“unchecked”)
Eitem=(E)s.readObject();
if(item==null){
break;
}
add(item);
}
}
}自定义线程池,增加每个线程处理的耗时,以及平均耗时、最大耗时、最小耗时,以及输出监控日志信息等等;动态修改线程池的类,通过Spring的监听器监控配置刷新方法,实现动态更新线程池的参数;DynamicThreadPoolPropertiesController对外暴露两个方法,第一个通过ContextRefresher提供对外刷新配置的接口,实现及时更新配置信息,第二提供一个查询接口的方法,整体上的流程到这里就完成了,算是一个Demo版,对于该组件更深入的思考我认为还可以做以下三件事情:应该以starter的形式嵌入到应用,通过判断启动类加载的Appllo、Nacos还是默认实现;对外可以Push、也可以是日志,还可以支持各种库,提供丰富的输出形式,这个到此,关于“基于SpringBoot的线程池监控问题如何解决”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注百云主机网站,小编会继续努力为大家带来更多实用的文章!

相关推荐: Laravel如何仅更新时间戳和关联时间戳

这篇文章将为大家详细讲解有关Laravel如何仅更新时间戳和关联时间戳,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。仅更新时间戳和关联时间戳与上一个例子恰好相反,也许您需要仅更新 updated_at 字段,免费云主机域名而…

免责声明:本站发布的图片视频文字,以转载和分享为主,文章观点不代表本站立场,本站不承担相关法律责任;如果涉及侵权请联系邮箱:360163164@qq.com举报,并提供相关证据,经查实将立刻删除涉嫌侵权内容。

(0)
打赏 微信扫一扫 微信扫一扫
上一篇 08/13 12:03
下一篇 08/13 12:04

相关推荐