Java8中的异步编程

本文摘抄于《Java8笔记》,如有不明确的地方,请查看原书,仅做笔记用处。

Future

将耗时的操作封装到Callable对象中,然后提交给ExecutorService。
例子如下:

Future<Double> future = executor.submit(new Callable<Double>()){
		public Double call(){
			return doSomeLongComputation();
		}
}
try{
	Double result = future.get(1,TimeUnit.SECONDS);
} catch (ExecutionException ee){
	//计算抛出一个异常
} catch (InterruptedException ie){
	//当前线程在等待过程中被中断
} catch (TimeoutException te){
	//在Future对象完成之前超过已过期
}

CompletableFuture

常规处理
public Future<Double> getPriceAsync(String product) {
	CompletableFuture<Double> futurePrice = new CompletableFuture<>();
	//在另一个线程中以异步方式执行计算
	new Thread( () -> {
		double price = calculatePrice(product);
		//设置future的返回值
		futurePrice.complete(price);
	}).start();
	return futurePrice;
}

/*做其他的工作*/

//从future对象中读取数据,会进行等待
double price = futurePrice.get();
Future中的异常处理
public Future<Double> getPriceAsync(String product) {
	CompletableFuture<Double> futurePrice = new CompletableFuture<>();
	new Thread( () -> {
		try {
			double price = calculatePrice(product);
			futurePrice.complete(price);
		} catch (Exception ex) {
			//失败了,将异常放到future中,在获取时就会把异常抛出去
			futurePrice.completeExceptionally(ex);
		}
	}).start();
	return futurePrice;
}
使用工厂方法创建
public Future<Double> getPriceAsync(String product) {
	return CompletableFuture.supplyAsync(() -> calculatePrice(product));
}
创建自定义的执行器

因为默认线程池的数目是固定的,因此可能效率会有问题,因此在某些情况下,需要创建自定义的执行器。

private final Executor executor = Executors.newFixedThreadPool(Math.min(shops.size(), 100),new ThreadFactory() {
	public Thread newThread(Runnable r) {
		Thread t = new Thread(r);
		t.setDaemon(true);
		return t;
	}
});
CompletableFuture.supplyAsync(() -> shop.getName() + " price is " + shop.getPrice(product), executor);

多个异步任务进行流水线操作

public List<String> findPrices(String product) {
	List<CompletableFuture<String>> priceFutures = shops.stream()
		.map(shop -> CompletableFuture.supplyAsync(() -> shop.getPrice(product), executor))
		//进行同步的操作
		.map(future -> future.thenApply(Quote::parse))
		//将上一个异步任务与下一个异步任务进行连接,流水线操作。
		.map(future -> future.thenCompose(quote ->
					CompletableFuture.supplyAsync(
					() -> Discount.applyDiscount(quote), executor)))
		.collect(toList());
	return priceFutures.stream()
		//取得返回值
		.map(CompletableFuture::join)
		.collect(toList());
}

其中:

thenCompose和前一个任务是在同一个线程中运行。
thenComposeAsync和前一个任务会将后续的任务提交到一个线程池,每个任务是由不同的线程处理的。
两个任务异步整合
//这里面相当是有三个CompletableFuture,前两个计算过后,由第三个进行整合。
Future<Double> futurePriceInUSD = CompletableFuture.supplyAsync(() -> shop.getPrice(product))
	.thenCombine(CompletableFuture.supplyAsync(
		() -> exchangeService.getRate(Money.EUR, Money.USD)),
	(price, rate) -> price * rate
);
//其中thenCombineAsync是thenCombine的异步版本
处理完成后的异步任务流水线
//接收一个function来处理异步任务的返回值。
CompletableFuture[] futures = findPricesStream("myPhone").map(f -> f.thenAccept(System.out::println)).toArray(size -> new CompletableFuture[size]);
//接收一个数组,等所有的异步任务完成后,返回一个CompletableFuture<Void>对象。
CompletableFuture.allOf(futures).join();
//还有一个方法叫做antOf,类似于allof,不过他是只获取一个结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值