您的位置:首页 > 编程语言 > Java开发

多线程中线程执行器java5

2016-04-12 19:08 239 查看
执行器框架(Executor Framework),围绕着Executor 接口和它的子接口ExecutorService,以及实现这两个接口的ThreadPoolExecutor类的展开。

这套机制分离了任务的创建和执行。通过使用执行器,仅需要实现Runnable接口的对象,然后将这些对象发送给执行器即可。执行器通过创建所需的线程,来负责这些Runnable对象的创建,实例化及运行。但执行器的功能不限于此,它使用了线程池来提高应用程序的性能。但发送一个任务给执行器时,执行器会尝试使用线程池中的线程来执行这个任务,避免了不断地创建和销毁线程而导致系统性能下降。

执行器框架另一个重要的优势是Callable接口。它类似于Runnable接口,但是却提供了两方面的增强。

这个接口的主要方法名称为call(),可以返回结果

当发送一个Callable对象给执行器时,将获得一个实现Future接口的对象,可以使用这个对象来控制Callable对象的状态和结果。

仅当线程的数量时合理的或者线程只会远行很短时间时,适合采用Executors工厂类的newCachedThreadPool()方法来创建执行器。

一旦创建了执行器,就可以使用执行器的execute()方法来发送Runnable或Callable类型的任务。

getPoolSize():返回执行器线程池中实际的线程数

getActiveCount():返回执行器中正在执行任务的线程数

getCompletedTaskCount():返回执行器已完成的任务数

为了完成执行器的执行,可以使用ThreadPoolExecutor类的shutdown()方法。

Executors工厂类也提供newSingleThreadExecutor()方法。这是一个创建固定大小线程执行器的极端情况,它将创建一个只有单个线程的执行器。因此这个执行器只能同一时间执行一个任务。

执行框架(Executor Framework)的优势之一是,可以运行并发任务并返回结果。

Callable:这个接口声明了call()方法。Callable接口是一个泛型接口,这就意味着必须声明call()方法返回的数据类型。

Future:这个接口声明了一些方法来获取由Callable对象产生的结果,并管理它们的状态

submit()方法接受Callable对象作为参数,并返回Future对象。Future对象可以使用以下两个主要目的。

控制任务的状态:可以取消任务和检查任务是否完成。为了达到这个目的,可以使用isDone()方法来检查任务是否已经完成

在调用Future对象的get()方法时,如果Future对象所控制的任务并未完成,那么这个方法将一直阻塞到任务完成。Future接口也提供了get()方法的其他调用方式

ThreadPoolExecutor类的invokeAny()方法接收到一个任务列表,然后运行任务,并返回第一个完成任务并且没有抛出异常的任务的执行结果。这个方法返回的类型与任务里的call()方法返回的类型相同

如果多个任务(两个)都返回值,那么invokeAny()方法的结果就是首先完成任务的名称。

如果第一个任务返回值,第二个任务抛出Exception异常,那么invokeAny()方法的结果就是第一个

如果第一个任务抛出Exception异常,第二个任务返回值,那么invokeAny()方法的结果是第二个

如果都抛出Exception异常,那么invokeAny()将抛出异常

invokeAll()方法等待所有任务完成。这个方法接收一个Callable对象列表,并且返回一个Future对象列表。在这个列表中,每一个任务对应一个Future对象。Future对象列表中的第一个对象控制Callable列表中的第一个任务,以此类推

需要注意的一点是,在存储结果的列表声明中,用在Future接口中的泛型参数的数据类型必须与Callable接口的泛型数据类型相兼容

另一个关于invokeAll(),使用Future对象仅用来获取任务的结果。当所有的任务执行结束时这个方法也执行结束了,如果在返回的Future对象上调用isDone()方法,那么所有的调用将返回true

使用执行器时,不需要管理线程,只需要实现Runnable或Callable任务并发送任务给执行器即可。执行器负责创建线程,管理线程池中的线程,当线程中不需要时就销毁它们。有时候,我们可能需要取消已经发送给执行器的任务。在这中情况下,可以使用Future接口中的cancel()方法来执行取消操作

如果任务已经完成,或者之前已经被取消,或者是由于某种原因而不能被取消,那么这个方法将返回false并且任务也不能取消

如果任务在执行器中等待分配Thread对象来执行它,那么任务被取消,并且不会开始执行。如果任务已经在远行,那么他依赖于调用cancel()方法是传递的参数。如果传递参数位true并且任务在运行,那么任务将被取消。如果传递的参数位false并且任务正在执行,那么任务不会被取消。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: