多线程 - 线程池的实现

来源:互联网 发布:淘宝发货地址怎么修改 编辑:程序博客网 时间:2024/06/05 10:02

概述


系统启动一个新线程的成本是比较高的,因为它需要与系统交互,使用线程池可以有效地控制系统中并发线程的数量。尤其是当系统中需要创建大量生命周期很短的线程时,这种效果尤为明显。
线程池会在程序启动时创建一定数量的线程。当程序将一个Runnable对象或Callable对象传给线程池,线程池会启动一个线程来执行它的run()方法或call()方法。当run()方法或call()方法执行结束后,该线程不会立刻死亡,而是再次返回线程池中成为空闲状态,等待执行下一个任务。

API


从Java 5以后,JDK新增了一个Executors工厂类来创建线程池,该工厂类包含如下几个静态方法:
  • newCachedThreadPool():创建一个具有缓冲功能的线程池,系统根据需要创建线程,这些线程将会被缓存在线程池中。
  • newFixedThreadPool(int nThreads):创建一个可重用、具有固定线程数的线程池。
  • newSingleThreadExecutor():创建一个只有一个线程的线程池。
  • newScheduledThreadPool(int corePoolSize):创建具有指定线程数的线程池,它可以在指定延迟后执行任务。corePoolSize指线程池中所保存的线程数,即使线程是空闲的也被保存在线程池内。
  • newSingleThreadScheduledExecutor():创建只有一个线程的线程池,它可以在指定延迟后执行任务。
前3个方法返回一个ExecutorService对象,它代表线程池,可以执行Runnable或Callable任务。后2个方法返回一个ScheduledExecutorService对象,它是ExecutorService的子类,在指定延迟后执行线程任务。ExecutorService提供了3个方法来执行线程任务:
  • Future<?> submit(Runnable task):将一个Runnable任务提交给线程池,线程池将在有空闲线程是执行Runnable任务。Future对象代表Runnable任务的返回值——run()方法没有返回值,将返回null。
  • <T> Future<T> submit(Runnable task, T result):将一个Runnable任务提交给线程池,线程池将在有空闲线程是执行Runnable任务。其中result表示返回值,线程执行结束后返回result。
  • <T> Future<T> submit(Callable<T> task):将一个Callable任务提交给线程池,线程池将在有空闲线程是执行Callable任务。Future对象代表Callable任务的返回值。
当执行完线程任务后,应该关闭线程池。调用shutdown()方法后,线程池将不再接收新的线程任务,并将所有正在执行的线程任务执行完毕后关闭线程池。shutdownNow()方法会停止所有正在执行的线程任务并关闭线程池。

代码示例


使用线程池来执行线程任务的步骤如下:
(1)调用Executors类的静态工厂方法创建一个ExecutorService对象,该对象代表一个线程池;
(2)创建Runnable实现类或Callable实现类的实例,作为线程任务;
(3)调用ExecutorService对象的submit()方法来提交线程任务;
(4)线程任务执行完毕后,关闭线程池。

package Demo;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;class MyTask implements Runnable {    @Override    public void run() {for (int i = 0; i < 100; i++) {    System.out.println(Thread.currentThread().getName() + "的i值为" + i);}    }}public class ThreadPoolDemo {    public static void main(String[] args) {// 创建线程池,容量为4ExecutorService threadPool = Executors.newFixedThreadPool(4);// 提交三个线程任务threadPool.submit(new MyTask());threadPool.submit(new MyTask());threadPool.submit(new MyTask());// 关闭线程池threadPool.shutdown();    }}
测试结果:
pool-1-thread-1的i值为0pool-1-thread-2的i值为0pool-1-thread-2的i值为1pool-1-thread-2的i值为2pool-1-thread-3的i值为0pool-1-thread-2的i值为3pool-1-thread-1的i值为1pool-1-thread-2的i值为4pool-1-thread-2的i值为5pool-1-thread-2的i值为6pool-1-thread-3的i值为1pool-1-thread-2的i值为7pool-1-thread-2的i值为8pool-1-thread-2的i值为9pool-1-thread-2的i值为10pool-1-thread-2的i值为11pool-1-thread-2的i值为12pool-1-thread-2的i值为13......

0 0
原创粉丝点击