java ThreadPoolExecutor创建线程执行器

是什么?为什么?怎么做?

感谢:http://blog.csdn.net/guozehao520/article/details/39136533

 

一、是什么

ThreadPoolExecutor是java.util.concurrent包提供的一个线程池类。

可以使用ThreadPoolExecutor创建一个线程执行器,负责线程的创建和执行。

二、为什么

这个问题等价于“为什么使用线程池”。

1.传统线程的劣势

通常使用Java开发一个简单的并发应用程序时,会创建一些Runnable对象,然后创建对应的Thread对象来执行它们。但是,如果需要开发一个程序来运行大量的并发任务,这个方法将会突显以下几种劣势:

(1)所有代码都需要手工实现

必须手动实现所有与Thread对象管理相关的代码,比如线程的创建、结束、结果获取。如果Thread对象很多,手动实现将非常繁琐。

(2)大量的Thread对象

每一条线程都需要创建一个单独的Thread对象。如果大量并发,很可能需要管理和维护大量的Thread对象。

(3)不能无限制地创建线程

硬件存在限制,计算资源是一定的,不能无限制地创建线程。

2.解决方案

自从java5开始,java并发Api提供了一套解决这些问题的机制,这套机制就是执行器框架,围绕着Executor接口和它的子接口ExecutorService,以及实现这两个接口的ThreadPoolExecutor类展开。

特别需要注意Executor、ExecutorService、ThreadPoolExecutor这三者的关系:

Executor是最上级接口,ExecutorService是Executor的子接口,ThreadPoolExecutor是实现了ExecutorService接口的实现类(也可以说是同时实现了这两个接口)。

这套机制可以分离的任务的创建和执行。

(1)创建等操作可以交给执行器

通过使用执行器,仅需要Runnable接口的对象,然后将这些对象发送给执行器即可。执行器通过创建所需的线程,来负责这些Runnable对象的创建,实例化以及运行。(解决了问题一)。

(2)执行器实现了线程池

执行器使用了线程池来提高应用程序的性能。当发送一个任务给执行器时,执行器会尝试使用线程池中的线程来执行这个任务,不需要大量创建Thread对象(解决了问题二),避免了不断创建和销毁线程而导致系统性能下降(解决了问题三)。

(3)执行器方便实用callable接口

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

1.这个接口的主方法名称是call,可以返回线程执行的结果。

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

这个特点我还没有实践过,后面我会进行尝试。

三、怎么做

test.java

在这里,我们自定义了一个线程执行器。只需要初始化继承了Runnable的线程类,交给线程执行器的executeTask方法执行即可。

运行结果:

我们也可以使用ExecutorService代替这里的ThreadPoolExecutor,代价就是不能使用ThreadPoolExecutor实现类中的部分方法:

四、总结

要体会线程执行器的思想。

发表评论

电子邮件地址不会被公开。 必填项已用*标注