简单解析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}
*/
publicFuturesubmit(Runnabletask,Tresult){
if(task==null)thrownewNullPointerException();
RunnableFutureftask=newTaskFor(task,result);
execute(ftask);
returnftask;
}
/**
*@throwsRejectedExecutionException{@inheritDoc}
*@throwsNullPointerException{@inheritDoc}
*/
publicFuturesubmit(Callabletask){
if(task==null)thrownewNullPointerException();
RunnableFutureftask=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{
Callablec=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方法。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。