在大规模应用中,创建、分配和释放多线程对象会产生大量内存管理开销,可以考虑使用Java提供的线程池来创建多线程进一步优化线程管理。

1.Executor 接口实现线程池管理

从JDK5开始,在java.util.concurrent包下增加了Executor接口及其子类,允许使用线程池技术来管理线程并发问题。Executor接口提供了一个常用的ExecutorService子接口,通过该子接口可以方便进行线程池管理。

通过Executor接口实现线程池管理的主要步骤如下:

(1)创建Runnable接口或者Callable接口的实现类,同时重写run()或者call()方法;

(2)创建Runnable接口或者Callable接口的实现类对象;

(3)使用Executor线程执行器类创建线程池;

(4)使用ExecutorService执行器服务类的submit()方法将Runnable接口或者Callable接口的实现类对象提交到线程池进行管理;

(5)线程任务执行完成后,可以使用shutdown()方法关闭线程池。

表10-4 Executors创建线程池的方法

方法声明

功能描述

ExecutorService newCachedThreadPool()

创建一个可扩展线程池的执行器。这个线程池执行器适用于启动许多短期任务的应用程序

ExecutorService newFixedThreadPool(int nThread)

创建一个固定线程数量线程池的执行器。这种线程池执行器可以很好地控制多线程任务,也不会导致由于响应过多导致地程序崩溃

ExecutorService newSingleThreadExecutor()

在特殊需求下创建一个只执行一个任务地单个线程。

ScheduledExecutorService newScheduledThreadPool(int corePoolSize)

创建一个定长线程池,支持定时及周期性任务执行

 

伪代码例子:

//自己实现地线程
Mythread  mythread = new Mythread();
ExecutorService executor = ExecutorService.newCachedThreadPool();
Future<Object> result1 = executor.submit(mythread);
Future<Object> result2 = executor.submit(mythread);
executor.shutdown();

2.CompletableFuture类实现线程池管理

在使用Callable接口实现多线程时,会用到FutureTask类对多线程执行结果进行管理和获取,由于该类获取结果时是通过阻塞或者轮询地方式,违背多线程编程地初衷并且耗费过多资源,因此JDK8中对FutureTask存在地不足进行了改进,增加了一个强大地函数式异步编程辅助类CompletableFuture,该类同时实现了Future接口和CompletionStage接口(jdk8中增加地一个线程任务完成结果接口)

CompletableFuture通常使用4个静态方法来为一段异步执行地代码创建CompletableFuture对象

CompletableFuture对象创建地4个静态方法

方法

功能

static CompletableFuture<Void> runAsync(Runnable runnable)

以Runnable函数式接口类型为参数,并使用ForkJoinPool.commonPool()作为它的线程池执行异步代码获取CompletableFuture计算结果为空地对象

static CompletableFuture<Void> runAsync(Runnable runnable,Executor executor)

以Runnable函数式接口类型为参数,并传入指定地线程池执行器executor来获取CompletableFuture计算结果为空地对象

static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)

以Supplier函数式接口类型为参数,并使用ForkJoinPool.commonPool()作为它的线程池执行异步代码获取CompletableFuture计算结果为非空地对象

static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier,Executor executor)

以Supplier函数式接口类型为参数,并传入指定地线程池执行器executor来获取CompletableFuture计算结果为非空地对象

 

用法示例:

 

public static void main(String args[]) throws InterruptedException,ExecutionException{
         CompletableFuture<Integer> completableFutute1 = CompletableFuture.supplyAsync(()->{
             int sum = 0,i=0;
             while(i++<5){
                 sum+=i;
             }
             return sum;            });
         CompletableFuture<Integer> completableFutute2 = CompletableFuture.supplyAsync(()->{
             int sum = 0,i=5;
             while(i++<10){
                 sum+=i;
             }
             return sum;            });
         CompletableFuture<Integer> completableFutute3 = completableFutute1.thenCombine(completableFutute2, 
                 (result1,result2)->result1+result2);
         System.out.print(completableFutute3.get());
     }