threadpoolexecutor中的submit()方法详细讲解-mile米乐体育
目录
- submmit()参数解析
- submit()的返回值future
- futuretask的get()的实现
- submit()使用案例
在使用线程池的时候,发现除了execute()方法可以执行任务外,还发现有一个方法submit()可以执行任务。
submit()有3个参数不一的方法,这些方法都是在executorservice接口中声明的,在abstractexecutorservice中实现,而threadpoolexecutor继承abstractexecutorservice。
我们可以看到submit()的参数既可以是run恰卡编程网nable,又可以是callable。对于runnable我们是比较熟的,它是线程thread所执行的任务,里面有一个run()方法,是任务的具体执行操作。那么callable呢?我们一起看下他们的代码吧。
public interface runnable { void run(); } public interface callable
runnable这里就不介绍了,callable接口定义了一个call()方法,返回一个callable指定的泛型类,并且call()调用的时候会抛出异常。通过比较runnable和callable还看不什么端倪,那么我们就看看内部实现吧。
submmit()参数解析
这里重点分析submit()带参数runnable和callable的方法
public future&l leaked interrupts int s = state; if (s >= interrupting) handlepossiblecancellationinterrupt(s); } }
我们在new futuretask()对象的时候,在futuretask构造方法中会对state状态赋值为new,并且传入一个callable对象。通过futuretask的run()我们可以知道,其实就通过state状态判断,调用callable的call()。(如果传入的参数是runnable,runnable在runnableadapter类中转化时,在call()中,其实调用的就是runnable的run()方法)。
所以在submit()方法中,调用了一个execute(task)的方法,实际执行的是futuretask的run(),而futuretask的run()调用的是callable的call()方法。
说了这么多,submit()最后执行的还是传入的runnable的run()或callable的call()方法。好像没有futuretask什么事啊。
其实不是,submit()返回futuretask对象,通过这个futuretask对象调用get()可以返回submit()方法传入的一个泛型类参数result对象,如果是callable直接通过call()返回。这个返回值的可以用来校验任务执行是否成功。
futuretask的get()的实现
public v get() throws interruptedexception, executionexception { int s = state; if (s <= completing) s = awaitdone(false, 0l); //等待任务执行完 return report(s);//将执行的任务结果返回 } private v report(int s) throws executionexception { object x = outcome; if (s == normal) return (v)x; if (s >= cancelled) throw new cancellationexception(); throw new executionexception((throwable)x); }
最后是通过outcome参数将根据任务的状态将结果返回。那么outcome参数在哪里赋值了?outcome参数赋值的地方有好2处,一是futuretask的set(),二是futuretask的setexception()。
set()是在futuretask的run()执行完成后,将传入的result参数赋值给传入给set(),赋值给outcome参数。如果run()报异常了会将throwable对象通过setexception()方法传入,赋值给outcome变量
大家可以返回上面的run()查看下。
protected void set(v v) { if (u.compareandswapint(this, state, new, completing)) { outcome = v; u.putorderedint(this, state, normal); // final state finishcompletion(); } } protected void setexception(throwable t) { if (u.compareandswapint(this, state, new, completing)) { outcome = t; u.putorderedint(this, state, exceptional); // final state gseyvs finishcompletion(); } }
submit()使用案例
public class test { private static final string success = "success"; public static void main(string[] args) { executorservice executorservice = executors.newfixedthreadpool(3); system.out.println("------------------任务开始执行---------------------"); future
打印结果:
------------------任务开始执行---------------------
call()调用开始: 1496899867882
submit方法执行任务完成: 1496899872897 thread name: pool-1-thread-1
经过返回值比较,submit方法执行任务成功 thread name: main
-------------------main thread end---------------------
主线程会一直阻塞,等待线程池中的任务执行完后,在执行后面的语句。
到此这篇关于threadpoolexecutor中的submit()方法详细讲解的文章就介绍到这了,更多相关threadpoolexecutor submit()方法内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!