多线程-线程执行器

参考资料:

https://blog.csdn.net/bairrfhoinn/article/details/16848785

https://www.cnblogs.com/zhrb/p/6372799.html

https://blog.csdn.net/u010412719/article/details/52489843

newSingleThreadExecutor:创建一个单线程的线程池。这个线程池只有一个线程在工作,也就是相当于单线程串行执行所有任务。如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。此线程池保证所有任务的执行顺序按照任务的提交顺序执行。

Executors相当于执行器的工厂类,包含各种常用执行器的工厂方法,可以直接创建常用的执行器。几种常用的执行器如下:

Executors.newCachedThreadPool,根据需要可以创建新线程的线程池。线程池中曾经创建的线程,在完成某个任务后也许会被用来完成另外一项任务。
Executors.newFixedThreadPool(int nThreads) ,创建一个可重用固定线程数的线程池。这个线程池里最多包含nThread个线程。
Executors.newSingleThreadExecutor() ,创建一个使用单个 worker 线程的 Executor。即使任务再多,也只用1个线程完成任务。
Executors.newSingleThreadScheduledExecutor() ,创建一个单线程执行程序,它可安排在给定延迟后运行命令或者定期执行。

Executor与ExecutorService的常用方法

execute方法:

Executor接口只有void execute(Runnable command)方法。从方法声明中我们可以看到入参为Runnable类型对象。常用的例子如下:
Executor executor = anExecutor;
executor.execute(new RunnableTask1());
但里面具体怎么执行,是否调用线程执行由相应的Executor接口实现类决定。比如前面的newCachedThreadPool使用线程池来进行执行。Executor将任务提交与每个任务如何运行(如何使用线程、调度)相分离。

submit方法:

ExecutorService接口继承自Executor接口,扩展了父接口中的execute方法。有两个常用的submit方法
Future<?> submit(Runnable task)
Future submit(Callable task)
可以看到这两个常用方法一个接收Runnable类型入参,一个接收Callable类型入参。Callable入参允许任务返回值,而Runnable无返回值。也就是说如果我们希望线程有一个返回结果,我们应该使用Callable类型入参。

invokeAll与invokeAny方法:

批量执行一组Callable任务。其中invokeAll是等所有任务完成后返回代表结果的Future列表。而invokeAny是等这一批任务中的任何一个任务完成后就返回。从两个方法的返回结果我们也可以看出两个方法的不同:
List<Future> invokeAll(Collection<? extends Callable> tasks)
T invokeAny(Collection<? extends Callable> tasks)
invokeAll返回的是List<Future,而invoke返回的是T。

shutdown()方法:

启动一次顺序关闭,执行以前提交的任务,但不接受新任务。执行此方法后,线程池等待任务结束后就关闭,同时不再接收新的任务。如果执行完shutdown()方法后,再去执行execute方法则直接抛出RejectedExecutionException。不要问我为什么知道...刚从坑里爬出来。
原则:只要ExecutorService(线程池)不再使用,就应该关闭,以回收资源。要注意这个不再使用。
上述方法较多,可以配合后面的实例进行理解。可以先记住execute方法与shutdown方法。

posted on 2018-11-26 20:35  黑白熊熊  阅读(218)  评论(0编辑  收藏  举报

导航