简单解析execute和submit有什么区别
1、execute方法位于java.util.concurrent.Executor中
voidexecute(Runnablecommand);
2、execute的具体实现
publicvoidexecute(Runnablecommand){ if(command==null) thrownewNullPointerException(); /* *Proceedin3steps: * *1.IffewerthancorePoolSizethreadsarerunning,tryto *startanewthreadwiththegivencommandasitsfirst *task.ThecalltoaddWorkeratomicallychecksrunStateand *workerCount,andsopreventsfalsealarmsthatwouldadd *threadswhenitshouldn't,byreturningfalse. * *2.Ifataskcanbesuccessfullyqueued,thenwestillneed *todouble-checkwhetherweshouldhaveaddedathread *(becauseexistingonesdiedsincelastchecking)orthat *thepoolshutdownsinceentryintothismethod.Sowe *recheckstateandifnecessaryrollbacktheenqueuingif *stopped,orstartanewthreadiftherearenone. * *3.Ifwecannotqueuetask,thenwetrytoaddanew *thread.Ifitfails,weknowweareshutdownorsaturated *andsorejectthetask. */ intc=ctl.get(); if(workerCountOf(c)3、submit方法位于java.util.concurrent.AbstractExecutorService中
/** *@throwsRejectedExecutionException{@inheritDoc} *@throwsNullPointerException{@inheritDoc} */ publicFuture>submit(Runnabletask){ if(task==null)thrownewNullPointerException(); RunnableFutureftask=newTaskFor(task,null); execute(ftask); returnftask; } /** *@throwsRejectedExecutionException{@inheritDoc} *@throwsNullPointerException{@inheritDoc} */ public Future submit(Runnabletask,Tresult){ if(task==null)thrownewNullPointerException(); RunnableFuture ftask=newTaskFor(task,result); execute(ftask); returnftask; } /** *@throwsRejectedExecutionException{@inheritDoc} *@throwsNullPointerException{@inheritDoc} */ public Future submit(Callable task){ if(task==null)thrownewNullPointerException(); RunnableFuture ftask=newTaskFor(task); execute(ftask); returnftask; } 4、submit方式使用Runnable入参时的具体实现
staticfinalclassRunnableAdapterimplementsCallable { finalRunnabletask; finalTresult; RunnableAdapter(Runnabletask,Tresult){ this.task=task; this.result=result; } publicTcall(){ task.run(); returnresult; } } 5、submit方式使用Callable入参时的具体实现
publicFutureTask(Callablecallable){ if(callable==null) thrownewNullPointerException(); this.callable=callable; this.state=NEW;//ensurevisibilityofcallable } //重写run方法 publicvoidrun(){ if(state!=NEW|| !UNSAFE.compareAndSwapObject(this,runnerOffset, null,Thread.currentThread())) return; try{ Callable c=callable; if(c!=null&&state==NEW){ Vresult; booleanran; try{ result=c.call(); ran=true; }catch(Throwableex){ result=null; ran=false; setException(ex); } if(ran) set(result); } }finally{ //runnermustbenon-nulluntilstateissettledto //preventconcurrentcallstorun() runner=null; //statemustbere-readafternullingrunnertoprevent //leakedinterrupts ints=state; if(s>=INTERRUPTING) handlePossibleCancellationInterrupt(s); } } 总结:
1、根据源码可以看到execute仅可以接受Runnable类型,而submit重载了三个方法,参数可以是Runnable类型、Runnable类型+泛型T、Callable类型接口。
2、从上面源码可以看出submit方法实际上如果用Runnable类型的接口可以有返回值,也可以没有返回值。
3、传递Runnable类型接口加泛型T会被进一步封装,在Executors这个类里面有个内部类RunnableAdapter实现了Callable接口。
4、看submit方法可以看出,submit最终也是在调用execute方法,无论是Runnable还是Callable类型接口,都会被封装成FutureTask继续执行。
5、如果使用submit方法提交,会进一步封装成FutureTask,执行execute方法,在FutureTask里面重写的run方法里面调用Callable接口的call方法。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。