Guava(七)

13 篇文章 0 订阅

目录

【并发编程】
    并发编程是一个难题,但是一个强大而简单的抽象可以显著的简化并发的编写。出于这样的考虑,Guava 定义了 ListenableFuture 接口并继承了JDK concurrent包下的 Future 接口。Guava强烈建议在代码中多使用 ListenableFuture 来代替JDK的 Future, 因为:
● 大多数 Futures 方法中需要它。
● 转到 ListenableFuture 编程比较容易。
● Guava提供的通用公共类封装了公共的操作方方法,不需要提供Future和ListenableFuture的扩展方法。

一、Future
    在了解 ListenableFuture 之前,我们先对Java的 Future 简单了解下:
    Future 是实现Java多线程的方式之一,Future接口提供方法来检测任务是否被执行完,等待任务执行完获得结果,也可以设置任务执行的超时时间。可配合 ExecutorService、Callable使用。
1.通过 FutureTask 实现

private void FutureTest1() throws Exception {
	// 创建单任务线程池
	ExecutorService executor = Executors.newSingleThreadExecutor();
	// FutureTask 实现
	FutureTask<String> future = new FutureTask<String>(new Callable<String>() {
		@Override
		public String call() throws Exception {
			return "def";
		}
	});
	executor.execute(future);

	// 获取执行结果并设置超时时间
	System.out.println(future.get(200, TimeUnit.MILLISECONDS));
	// 关闭线程池
	if (!executor.isShutdown()) {
		executor.shutdown();
	}
}

2.通过 submit() 方法实现

private void FutureTest2() throws Exception {
	// 创建单任务线程池
	ExecutorService executor = Executors.newSingleThreadExecutor();
	// submit() 方法实现
	Future<String> future = executor.submit(new Callable<String>() {
		@Override
		public String call() throws Exception {
			return "abc";
		}
	});

	// 获取执行结果
	System.out.println(future.get());
	// 关闭线程池
	executor.shutdown();
}

补充:
JDK Executors 创建线程池的方法说明

方法说明
newCachedThreadPool()可变尺寸线程池
newFixedThreadPool(3)固定大小线程池
newScheduledThreadPool(2)延迟连接池
newSingleThreadExecutor()单任务线程池
newSingleThreadScheduledExecutor()单任务延迟连接池
newWorkStealingPool()并行执行线程池

注:可以了解下 Runnable接口 和 Callable接口 的差异。

二、Futures
    Guava提供了 FutureCallback 用于对Future的返回结果进行处理。FutureCallback 中实现了两个方法:
● onSuccess(V),在Future成功的时候执行,根据Future结果来判断。
● onFailure(Throwable),在Future失败的时候执行,根据Future结果来判断。

FutureCallback 通过 Futures 添加回调。
Futures 的其他常用工具:

方法说明
transformAsync(ListenableFuture, AsyncFunction<I, O>, Executor)返回一个新的ListenableFuture,该ListenableFuture 返回的result是由传入的AsyncFunction 参数指派到传入的 ListenableFuture中
transformAsync(ListenableFuture, AsyncFunction<I, O>,)返回一个新的ListenableFuture ,该ListenableFuture 返回的result是由传入的AsyncFunction 参数指派到传入的 ListenableFuture中
allAsList(Iterable<ListenableFuture)返回一个ListenableFuture ,该ListenableFuture 返回的result是一个List,List中的值是每个ListenableFuture的返回值,假如传入的其中之一fails或者cancel,这个Future fails 或者canceled
successfulAsList(Iterable<ListenableFuture)返回一个ListenableFuture ,该Future的结果包含所有成功的Future,按照原来的顺序,当其中之一Failed或者cancel,则用null替代
ListenableFuture<Integer> transform = Futures.transformAsync(future, new AsyncFunction<String, Integer>() {
	@Override
	public ListenableFuture<Integer> apply(String input) {
		// todo 将 ListenableFuture<String> 转为 ListenableFuture<Integer>
		return null;
	}
});

三、ListenableFuture
    ListenableFuture继承了Future,它允许注册回调方法(callbacks),在运算(多线程执行)完成的时候进行调用,或者在运算(多线程执行)完成后立即执行。
    ListenableFuture 中的基础方法是addListener(Runnable, Executor),该方法会在多线程运算完的时候,指定的Runnable参数传入的对象会被指定的Executor执行。

    对应JDK中的 ExecutorService.submit(Callable) 提交多线程异步运算的方式,Guava 提供了ListeningExecutorService 接口,该接口返回 ListenableFuture 而相应的 ExecutorService 返回普通的 Future。将 ExecutorService 转为 ListeningExecutorService,可以使用MoreExecutors.listeningDecorator(ExecutorService)进行装饰。

ListenableFuture的实现:

private void FutureTest3() throws Exception {
	ListeningExecutorService executor = MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor());
	ListenableFuture<String> future = executor.submit(new Callable<String>() {
		@Override
		public String call() throws Exception {
			return "ghi";
		}
	});

	// 添加回调
	Futures.addCallback(future, new FutureCallback<String>() {
		@Override
		public void onSuccess(String result) {
			System.out.println(result);
		}

		@Override
		public void onFailure(Throwable t) {
			t.printStackTrace();
		}
	});

	if (!executor.isShutdown()) {
		executor.shutdown();
	}
}

同理也可使用 ListenableFutureTask 来实现:

private void FutureTest4() throws Exception {
	ListeningExecutorService executor = MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor());
	ListenableFutureTask<String> futureTask = ListenableFutureTask.create(new Callable<String>() {
		@Override
		public String call() throws Exception {
			return "jkl";
		}
	});
	executor.execute(futureTask);

	System.out.println(futureTask.get());

	executor.shutdown();
}

通过加了一层修饰,就可以支持一些其他的操作,而在JDK concurrent中的Future是不行的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值