Guava并发(3)——实现的异步回调

一、说明:

1、装饰Concurrent包里的ExecutorService

ListeningExecutorService guavaExecutor = MoreExecutors
				.listeningDecorator(Executors.newSingleThreadExecutor());
2、ListenableFuture的创建

final ListenableFuture listenableFuture = guavaExecutor
				.submit(new Callable() {
			。。。。。。
				});

 3、ListenableFuture注册监听器,即异步调用完成时会在指定的线程池中执行注册的监听器 
  
listenableFuture.addListener(new Runnable() {
			。。。。。。
		}, Executors.newSingleThreadExecutor());

4、Futures方法进行Callback

Futures.addCallback(listenableFuture2, new FutureCallback() {
					@Override
					public void onSuccess(Tresult) {
						。。。。。。
					}
					@Override
					public void onFailure(Throwable t) {
					}
				}
		);

二、代码:

package com.wll.guava.concurrent;

import com.google.common.util.concurrent.*;
import java.util.concurrent.*;

/**
 * 使用guava实现异步回调 {@link java.util.concurrent.Future}
 * {@link com.google.common.util.concurrent.ListenableFuture}
 * {@link com.google.common.util.concurrent.FutureCallback}
 *
 * @author landon
 */
public class FutureCallbackExample {

	public static void main(String[] args) throws Exception {
		nativeFuture();
		Thread.sleep(3000L);

		guavaFuture();
		Thread.sleep(3000L);

		guavaFuture2();
	}


	public static void nativeFuture() throws Exception {
		// 原生的Future模式,实现异步
		ExecutorService nativeExecutor = Executors.newSingleThreadExecutor();
		Future nativeFuture = nativeExecutor
				.submit(new Callable() {
					@Override
					public String call() throws Exception {
						// 使用sleep模拟调用耗时
						TimeUnit.SECONDS.sleep(1);
						return  "[" + Thread.currentThread().getName() +"]: 并发包Future返回结果" ;
					}
				});
		// Future只实现了异步,而没有实现回调.所以此时主线程get结果时阻塞.或者可以轮训以便获取异步调用是否完成
		System.out.println("[" + Thread.currentThread().getName() +"]====>"+ nativeFuture.get());

	}
	public static void guavaFuture() throws Exception {
		System.out.println("-------------------------------- 神秘的分割线 -----------------------------------");
		// 好的实现应该是提供回调,即异步调用完成后,可以直接回调.本例采用guava提供的异步回调接口,方便很多.
		ListeningExecutorService guavaExecutor = MoreExecutors
				.listeningDecorator(Executors.newSingleThreadExecutor());
		final ListenableFuture listenableFuture = guavaExecutor
				.submit(new Callable() {

					@Override
					public String call() throws Exception {
						TimeUnit.SECONDS.sleep(1);
						return  "[" + Thread.currentThread().getName() +"]: guava的Future返回结果";
					}
				});

		// 注册监听器,即异步调用完成时会在指定的线程池中执行注册的监听器
		listenableFuture.addListener(new Runnable() {
			@Override
			public void run() {
				try {
					String logTxt = "[" + Thread.currentThread().getName() +"]: guava对返回结果进行异步CallBack(Runnable):"
							+ listenableFuture.get();
					System.out.println(logTxt);
				} catch (Exception e) {
				}
			}
		}, Executors.newSingleThreadExecutor());

		// 主线程可以继续执行,异步完成后会执行注册的监听器任务.
		System.out.println( "[" + Thread.currentThread().getName() +"]: guavaFuture1执行结束");
	}

	public static void guavaFuture2() throws Exception {
		System.out.println("-------------------------------- 神秘的分割线 -----------------------------------");
		// 除了ListenableFuture,guava还提供了FutureCallback接口,相对来说更加方便一些.
		ListeningExecutorService guavaExecutor2 = MoreExecutors
				.listeningDecorator(Executors.newSingleThreadExecutor());
		final ListenableFuture listenableFuture2 = guavaExecutor2
				.submit(new Callable() {
					@Override
					public String call() throws Exception {
						TimeUnit.SECONDS.sleep(1);
						String logText = "[" + Thread.currentThread().getName() +"]: guava的Future返回结果";
						System.out.println(logText);
						return logText;
					}
				});

		// 注意这里没用指定执行回调的线程池,从输出可以看出,默认是和执行异步操作的线程是同一个.
		Futures.addCallback(listenableFuture2, new FutureCallback() {
					@Override
					public void onSuccess(String result) {
						String logTxt = "[" + Thread.currentThread().getName() +"]=======>对回调结果【"+result+"】进行FutureCallback,经测试,发现是和回调结果处理线程为同一个线程";
						System.out.println(logTxt);
					}
					@Override
					public void onFailure(Throwable t) {
					}
				}
		);
		// 主线程可以继续执行,异步完成后会执行注册的监听器任务.
		System.out.println( "[" + Thread.currentThread().getName() +"]: guavaFuture2执行结束");
	}
}

三、执行结果

D:\DevPro\Java\jdk1.7.0_79\bin\java -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:62193,suspend=y,server=n -Dfile.encoding=UTF-8 -classpath "D:\DevPro\Java\jdk1.7.0_79\jre\lib\jce.jar;D:\DevPro\Java\jdk1.7.0_79\jre\lib\jfr.jar;D:\DevPro\Java\jdk1.7.0_79\jre\lib\management-agent.jar;D:\DevPro\Java\jdk1.7.0_79\jre\lib\resources.jar;D:\DevPro\Java\jdk1.7.0_79\jre\lib\charsets.jar;D:\DevPro\Java\jdk1.7.0_79\jre\lib\javaws.jar;D:\DevPro\Java\jdk1.7.0_79\jre\lib\deploy.jar;D:\DevPro\Java\jdk1.7.0_79\jre\lib\plugin.jar;D:\DevPro\Java\jdk1.7.0_79\jre\lib\jsse.jar;D:\DevPro\Java\jdk1.7.0_79\jre\lib\rt.jar;D:\DevPro\Java\jdk1.7.0_79\jre\lib\jfxrt.jar;D:\DevPro\Java\jdk1.7.0_79\jre\lib\ext\access-bridge-64.jar;D:\DevPro\Java\jdk1.7.0_79\jre\lib\ext\dnsns.jar;D:\DevPro\Java\jdk1.7.0_79\jre\lib\ext\jaccess.jar;D:\DevPro\Java\jdk1.7.0_79\jre\lib\ext\sunec.jar;D:\DevPro\Java\jdk1.7.0_79\jre\lib\ext\sunjce_provider.jar;D:\DevPro\Java\jdk1.7.0_79\jre\lib\ext\sunmscapi.jar;D:\DevPro\Java\jdk1.7.0_79\jre\lib\ext\zipfs.jar;D:\DevPro\Java\jdk1.7.0_79\jre\lib\ext\localedata.jar;E:\DevCode\guavaLearn\target\classes;C:\Users\Administrator\.m2\repository\com\google\guava\guava\18.0\guava-18.0.jar;C:\Users\Administrator\.m2\repository\org\mockito\mockito-all\2.0.2-beta\mockito-all-2.0.2-beta.jar;C:\Users\Administrator\.m2\repository\junit\junit\4.12\junit-4.12.jar;C:\Users\Administrator\.m2\repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;C:\Users\Administrator\.m2\repository\com\alibaba\fastjson\1.2.7\fastjson-1.2.7.jar;D:\DevPro\JetBrains\IntelliJ IDEA 14.0.2\lib\idea_rt.jar" com.wll.guava.concurrent.FutureCallbackExample
Connected to the target VM, address: '127.0.0.1:62193', transport: 'socket'
[main]====>[pool-1-thread-1]: 并发包Future返回结果
-------------------------------- 神秘的分割线 -----------------------------------
[main]: guavaFuture1执行结束
[pool-3-thread-1]: guava对返回结果进行异步CallBack(Runnable):[pool-2-thread-1]: guava的Future返回结果
-------------------------------- 神秘的分割线 -----------------------------------
[main]: guavaFuture2执行结束
[pool-4-thread-1]: guava的Future返回结果
[pool-4-thread-1]=======>对回调结果【[pool-4-thread-1]: guava的Future返回结果】进行FutureCallback,经测试,发现是和回调结果处理线程为同一个线程
Disconnected from the target VM, address: '127.0.0.1:62193', transport: 'socket'

Process finished with exit code -1

四、总结:

略。


你可能感兴趣的:(guava,JAVA并发包)