首页 理论教育 Java程序设计:线程池的使用

Java程序设计:线程池的使用

时间:2023-11-01 理论教育 版权反馈
【摘要】:对于执行很多短期异步任务的程序而言,这类线程池通常可提高程序性能。另外,终止并从缓存中移除那些已有60秒钟未被使用的线程,因此,长时间保持空闲的该类线程池不会使用任何资源。以上三种方法创建的线程池其实是java.util.concurrent.ThreadPoolExecutor类的对象。演示线程池的使用。图6-35利用线程池执行任务测试类Thread Pool Test中创建了一个固定线程数为3的线程池,并将创建好的两个任务提交到线程池中运行,由于线程池中有3个线程,因此,这两个任务可以并发执行。

Java程序设计:线程池的使用

Java的java.util.concurrent.Executors类提供了一系列静态工厂方法来创建各种线程池,返回的线程池都实现了ExecutorService接口。三种常用的方法如下:

(1)public static ExecutorService new Fixed ThreadPool(int n Threads)方法用于创建一个可重用且固定线程数(n Threads)的线程池。如果在所有线程处于活动状态时提交附加任务,则在有可用线程之前,附加任务将在队列中等待。

(2)public static ExecutorService newSingleThreadExecutor()方法用于创建单个线程的线程池,这个线程处理完一个任务后接着处理下一个任务。如果该线程因为异常而结束,则会新建一个线程来替代。

(3)public static ExecutorService newCached ThreadPool()方法创建一个线程池,它可以按需创建新线程,当以前构造的线程可用时将重用它们。对于执行很多短期异步任务的程序而言,这类线程池通常可提高程序性能。调用execute方法将重用以前构造的线程(如果线程可用);如果现有线程没有可用的,则创建一个新线程并添加到池中。另外,终止并从缓存中移除那些已有60秒钟未被使用的线程,因此,长时间保持空闲的该类线程池不会使用任何资源。

以上三种方法创建的线程池其实是java.util.concurrent.ThreadPoolExecutor类的对象。下面简单介绍ThreadPoolExecutor、Abstract ExecutorService、ExecutorService和Executor之间的关系。

(1)java.util.concurrent.Executor接口:Executor是一个顶层接口,在它里面只声明了一个抽象方法void execute(Runnable command),用来执行传进去的任务。其子接口和所有实现类如图6-32所示。

图6-32 Executor接口

(2)java.util.concurrent.ExecutorService接口:继承了Executor接口,并声明了submit、invokeAll、invoke Any、await Termination、shutdown等抽象方法,主要用来管理和控制任务。

(3)java.util.concurrent.ThreadPoolExecutor类:Thread PoolExecutor继承自抽象类java.util.concurrent.AbstractExecutorService,在抽象类Abstract ExecutorService中基本实现了ExecutorService接口声明的所有抽象方法。

在Thread Pool Executor类中有几个非常重要的方法:

(1)execute()方法实际上是Executor接口中声明的方法,在ThreadPoolExecutor类中进行了具体的实现,该方法是ThreadPoolExecutor类中的核心方法,通过这个方法可以向线程池提交一个任务,然后由线程池去执行。

(2)submit()方法是在ExecutorService中声明的方法,在Abstract ExecutorService抽象类中就有了具体的实现,在子类ThreadPoolExecutor中并没有对其进行重写。这个方法也是用来向线程池提交任务的,和execute()方法不同的是,它能够返回任务执行的结果,实际上该方法还是调用了execute()方法,只不过利用Future来获取任务执行结果。

(3)shutdown()和shutdown Now()是用来关闭线程池的。其他方法请参考API帮助文档。

【例6-11】(www.xing528.com)

演示线程池的使用。

步骤1:在chapter6工程src文件夹下新建一个包cn.linaw.chapter6.demo09,在包里创建任务类Task1.java,如图6-33所示。

图6-33 定义任务Task1类

步骤2:在包里创建任务类Task2.java,如图6-34所示。

图6-34 定义任务Task2类

步骤3:利用线程池执行多个任务,测试类ThreadPool Test如图6-35所示。

图6-35 利用线程池执行任务

(1)测试类Thread Pool Test中创建了一个固定线程数为3的线程池,并将创建好的两个任务提交到线程池中运行,由于线程池中有3个线程,因此,这两个任务可以并发执行。

(2)如果使用Executors.newSingle Thread Executor()方法或者Executors.new Fixed Thread Pool(1)方法创建线程池,则待执行的任务会按顺序执行,因为线程池里只有一个线程。

(3)如果使用Executors.new Cached ThreadPool()方法创建线程池,则会为每一个等待的任务创建一个新线程,这样所有的任务都能并发执行,当然,并发的任务数越多,对资源的消耗越大。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈