CompletableFuture

概要

CompletableFuture类简介

官网API地址
public class CompletableFuture implements Future, CompletionStage 】
CompletableFuture是Java 8中新增的一个用以异步处理的一个类,它实现了Future接口,对Future的功能进行了扩展。


get()、get(long timeout,TimeUnit unit)和getNow(T valueIfAbsent)

get()、get(long timeout,TimeUnit unit): 调用这两个方法都会阻塞当前线程,直到结束任务或者手动调用结束方法complete(T value)、completeExceptionally(Throwable ex)。不同的是,第二个方法可以指定超时时间,如果在指定时间内未完成任务,将会抛出 java.util.concurrent.TimeoutException异常。

getNow(T valueIfAbsent): 如果任务已完成,则返回结果;否则返回给定的默认值。注意该方法的调用不会导致阻塞。

示例:

package Main;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class Main {
	private static CompletableFuture<String> future;

	public static void main(String[] args) throws ExecutionException {
		future = CompletableFuture.supplyAsync(() -> {
			try {
				TimeUnit.SECONDS.sleep(3);
				System.out.println("run end");
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

			return "completable";
		});

		try {
			future.get();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		/*
		 * try { future.get(3, TimeUnit.SECONDS); } catch (InterruptedException |
		 * TimeoutException e) { // TODO Auto-generated catch block e.printStackTrace();
		 * }
		 */// java.util.concurrent.TimeoutException

		// Returns the result value (or throws any encountered exception) if completed,
		// else returns the given valueIfAbsent.
		System.out.println(future.getNow("default value"));
		System.out.println("end");
	}

}

runAsync(Runnable)和runAsync(Runnable,Executor)

runAsync接受的是Runnable对象,所以不存在返回值。

runAsync(Runnable):
返回一个新的CompletableFuture,它在运行给定操作后由ForkJoinPool.commonPool()中运行的任务异步完成。

package Main;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

public class RunAsync {

	public static void main(String[] args) {
		//Returns a new CompletableFuture that is asynchronously completed 
		//by a task running in the ForkJoinPool.commonPool() after it runs the given action.
		CompletableFuture future = CompletableFuture.runAsync(() -> {
			System.out.println("run");
		});

		try {
			future.get();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}

		System.out.println("end");
	}

}

runAsync(Runnable,Executor):
返回一个新的CompletableFuture,它运行在给定的线程池中。

package Main;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class RunAsync {

	public static void main(String[] args) {
		ExecutorService exec = Executors.newSingleThreadExecutor();
		CompletableFuture future = CompletableFuture.runAsync(new Runnable() {

			@Override
			public void run() {
				System.out.println("run");
			}

		}, exec);

		try {
			future.get();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}

		System.out.println("end");
	}

}

supplyAsync(Supplier)和supplyAsync(Supplier,Executor)

supplyAsync(Supplier)

package Main;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

public class SupplyAsync {

	public static void main(String[] args) {
		CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
			System.out.println("supplyAsync");
			return "return value";
		});

		try {
			System.out.println(future.get());
		} catch (InterruptedException | ExecutionException e) {
			e.printStackTrace();
		}
	}

}

supplyAsync(Supplier,Executor)

package Main;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class SupplyAsync {

	public static void main(String[] args) {
		ExecutorService exec = Executors.newSingleThreadExecutor();
		CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
			System.out.println("supplyAsync");
			return "return value";
		}, exec);

		try {
			System.out.println(future.get());
		} catch (InterruptedException | ExecutionException e) {
			e.printStackTrace();
		}
	}

}

thenApply 和 handle

如果两个任务之间有依赖关系,比如B任务依赖于A任务的执行结果,那么就可以使用这两个方法.
这两个方法,效果是一样的,区别在于,当A任务执行出现异常时,thenApply方法不会执行,而handle 方法一样会去执行,因为在handle方法里,我们可以处理异常,而前者不行。

package Main;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class Main {
   private static CompletableFuture<Integer> future;

   public static void main(String[] args) throws ExecutionException {
   	future = CompletableFuture.supplyAsync(() -> {
   		return 5;
   	}).thenApply((r) -> {
   		r = r + 1;
   		return r;
   	});

   	try {
   		System.out.println(future.get());
   	} catch (InterruptedException e1) {
   		e1.printStackTrace();
   	}

   	// 出现了异常,handle方法可以拿到异常 e
   	future.supplyAsync(() -> {
   		int i = 10 / 0;
   		return 5;
   	}).handle((r, e) -> {
   		System.out.println(e);
   		r = r + 1;
   		return r;
   	});
   }

}

thenCombine 和 thenAcceptBoth

我们常常需要合并两个任务的结果,在对其进行统一处理,简言之,这里的回调任务需要等待两个任务都完成后再会触发。这两者的区别 在于 前者是有返回值的,后者没有(就是个消耗工作)

package Main;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class Main {

	public static void main(String[] args) throws ExecutionException {
		CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			return "future1";
		});
		CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
			return "future2";
		});

		CompletableFuture<String> result = future1.thenCombine(future2, (r1, r2) -> {
			return r1 + r2;
		});

		try {
			System.out.println(result.get());
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

}

测试用例中的使用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值