1、CompletableFuture 可以很方便的实现异步任务的封装 并实现结果的联合等一系列操作,轻松实现 任务的并行
package com.csdn.test;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
* CompletableFuture 可以很方便的实现异步任务的封装 并实现结果的联合等一系列操作
*/
public class TestCompletableFuture
{
// CompletableFuture基本用法
private static Future<String> asyncTask(String input)
{
// CompletableFuture包装返回结果
CompletableFuture<String> future = new CompletableFuture<String>();
new Thread(()->{
try
{
TimeUnit.SECONDS.sleep(1);
}
catch (Exception ex)
{
ex.printStackTrace();
}
System.out.println("async task input value: " + input);
try
{
String ret = input.substring(1);
future.complete(ret);
}
catch(Exception ex)
{
// 封装异常
future.completeExceptionally(ex);
}
}).start();
return future;
}
// 使用工厂创建CompletableFuture
private static Future<String> asyncTask(int input)
{
return CompletableFuture.supplyAsync(() -> {
return String.valueOf(20/input);
});
}
// 异步处理流水线
private static List<String> asyncTaskPipeline(List<String> strList)
{
final Executor executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors(),
new ThreadFactory()
{
public Thread newThread(Runnable r)
{
Thread t = new Thread(r);
t.setDaemon(true); // 设置为守护线程,这种方式不会阻止程序的关停
return t;
}
});
List<CompletableFuture<String>> retFuture = strList.stream().map(str -> CompletableFuture.supplyAsync(()->str.trim(), executor))
.map(future -> future.thenApply(String::trim))
.map(future -> future.thenCompose(str -> CompletableFuture.supplyAsync(()->str.trim(), executor)))
.collect(Collectors.toList());
return retFuture.stream()
.map(CompletableFuture::join) // 等待流中Future执行完毕,提取各自返回值
.collect(Collectors.toList());
}
public static void main(String[] args)
{
String input = " trim";
System.out.println("async task start ...");
Future<String> future = asyncTask(input);
// 出现异常场景 验证
Future<String> futureInt = asyncTask(0);
// do something else
System.out.println("do something else...");
try
{
// 也可 CompletableFuture.allOf(futuresArr).join() 等待所有与future任务结束
String str = future.get();
System.out.println("async task result: " + str);
System.out.println("async task result: " + futureInt.get());
}
catch(Exception ex)
{
System.out.println("Exception: " + ex.getMessage());
}
String[] arr = new String[]{"aa", "bb "};
System.out.println(asyncTaskPipeline(Arrays.asList(arr)));
}
}
输出:
async task start ...
do something else...
async task input value: trim
async task result: trim
Exception: java.lang.ArithmeticException: / by zero
[aa, bb]
2、CompletionService 提供了异步任务的执行与结果的封装,轻松实现多线程任务,并方便的集中处理上述任务的结果(且任务最先完成的先返回)
package com.csdn.test;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class TestCompletionService
{
// 线程池超时关闭控制
private static final int TIMEOUT = 300000;
// 单位统一为毫秒
private static final TimeUnit UNIT = TimeUnit.MILLISECONDS;
// CompletableFuture基本用法
private static void asyncTask(int poolSize, List<String> strList)
{
// 1、创建线程池
ExecutorService executor = Executors.newFixedThreadPool(poolSize);
// 2、创建多线程任务执行器
CompletionService<String> completionService = new ExecutorCompletionService<String>(executor);
// 3、提交任务
for (String str : strList)
{
completionService.submit(new Callable<String>()
{
@Override
public String call() throws Exception
{
return str.trim();
}
});
}
// 4、获取数据
try
{
for (int taskCount = 0, size = strList.size(); taskCount < size; taskCount++)
{
System.out.println("future result: " + completionService.take().get());
}
}
catch (InterruptedException | ExecutionException e)
{
e.printStackTrace();
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
// 5、关闭线程池
try
{
executor.shutdownNow();
executor.awaitTermination(TIMEOUT, UNIT);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
public static void main(String[] args)
{
String[] arr = new String[]{"aa", "bb "};
asyncTask(2, Arrays.asList(arr));
}
}
输出:
future result: aa
future result: bb
参考书籍:
《Java8实战》
《Java并发编程实战》
参考博客: