引子:
aaarticlea/png;base64,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" alt="" />
上图是两个系统交互的情况,现在我想将对外系统的调用做成异步实现,那么就需要考虑两个问题:
可以使用Future模式来实现。
Future模式在请求发生时返回一个Future对象给发起请求的客户端,然后由一个新的线程执行真正的异步业务处理,当客户端需要异步处理的结果时,通过返回给客户端的Future对象的get()方法获取异步处理结果!
JDK的Future模式:Java.util.concurrent.future.Future接口
/**
* A <tt>Future</tt> represents the result of an asynchronous
* computation. Methods are provided to check if the computation is
* complete, to wait for its completion, and to retrieve the result of
* the computation. The result can only be retrieved using method
* <tt>get</tt> when the computation has completed, blocking if
* necessary until it is ready. Cancellation is performed by the
* <tt>cancel</tt> method. Additional methods are provided to
* determine if the task completed normally or was cancelled. Once a
* computation has completed, the computation cannot be cancelled.
* If you would like to use a <tt>Future</tt> for the sake
* of cancellability but not provide a usable result, you can
* declare types of the form {@code Future<?>} and
* return <tt>null</tt> as a result of the underlying task.
*
* <p>
* <b>Sample Usage</b> (Note that the following classes are all
* made-up.) <p>
* <pre> {@code
* interface ArchiveSearcher { String search(String target); }
* class App {
* ExecutorService executor = ...
* ArchiveSearcher searcher = ...
* void showSearch(final String target)
* throws InterruptedException {
* Future<String> future
* = executor.submit(new Callable<String>() {
* public String call() {
* return searcher.search(target);
* }});
* displayOtherThings(); // do other things while searching
* try {
* displayText(future.get()); // use future
* } catch (ExecutionException ex) { cleanup(); return; }
* }
* }}</pre>
*
* The {@link FutureTask} class is an implementation of <tt>Future</tt> that
* implements <tt>Runnable</tt>, and so may be executed by an <tt>Executor</tt>.
* For example, the above construction with <tt>submit</tt> could be replaced by:
* <pre> {@code
* FutureTask<String> future =
* new FutureTask<String>(new Callable<String>() {
* public String call() {
* return searcher.search(target);
* }});
* executor.execute(future);}</pre>
*
* <p>Memory consistency effects: Actions taken by the asynchronous computation
* <a href="package-summary.html#MemoryVisibility"> <i>happen-before</i></a>
* actions following the corresponding {@code Future.get()} in another thread.
*
* @see FutureTask
* @see Executor
* @since 1.5
* @author Doug Lea
* @param <V> The result type returned by this Future's <tt>get</tt> method
*/
public interface Future<V> { /**
* Attempts to cancel execution of this task. This attempt will
* fail if the task has already completed, has already been cancelled,
* or could not be cancelled for some other reason. If successful,
* and this task has not started when <tt>cancel</tt> is called,
* this task should never run. If the task has already started,
* then the <tt>mayInterruptIfRunning</tt> parameter determines
* whether the thread executing this task should be interrupted in
* an attempt to stop the task.
*
* <p>After this method returns, subsequent calls to {@link #isDone} will
* always return <tt>true</tt>. Subsequent calls to {@link #isCancelled}
* will always return <tt>true</tt> if this method returned <tt>true</tt>.
*
* @param mayInterruptIfRunning <tt>true</tt> if the thread executing this
* task should be interrupted; otherwise, in-progress tasks are allowed
* to complete
* @return <tt>false</tt> if the task could not be cancelled,
* typically because it has already completed normally;
* <tt>true</tt> otherwise
*/
boolean cancel(boolean mayInterruptIfRunning); /**
* Returns <tt>true</tt> if this task was cancelled before it completed
* normally.
*
* @return <tt>true</tt> if this task was cancelled before it completed
*/
boolean isCancelled(); /**
* Returns <tt>true</tt> if this task completed.
*
* Completion may be due to normal termination, an exception, or
* cancellation -- in all of these cases, this method will return
* <tt>true</tt>.
*
* @return <tt>true</tt> if this task completed
*/
boolean isDone(); /**
* Waits if necessary for the computation to complete, and then
* retrieves its result.
*
* @return the computed result
* @throws CancellationException if the computation was cancelled
* @throws ExecutionException if the computation threw an
* exception
* @throws InterruptedException if the current thread was interrupted
* while waiting
*/
V get() throws InterruptedException, ExecutionException; /**
* Waits if necessary for at most the given time for the computation
* to complete, and then retrieves its result, if available.
*
* @param timeout the maximum time to wait
* @param unit the time unit of the timeout argument
* @return the computed result
* @throws CancellationException if the computation was cancelled
* @throws ExecutionException if the computation threw an
* exception
* @throws InterruptedException if the current thread was interrupted
* while waiting
* @throws TimeoutException if the wait timed out
*/
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
对应的任务接口是:java.util.concurrent.Callable
/**
* A task that returns a result and may throw an exception.
* Implementors define a single method with no arguments called
* <tt>call</tt>.
*
* <p>The <tt>Callable</tt> interface is similar to {@link
* java.lang.Runnable}, in that both are designed for classes whose
* instances are potentially executed by another thread. A
* <tt>Runnable</tt>, however, does not return a result and cannot
* throw a checked exception.
*
* <p> The {@link Executors} class contains utility methods to
* convert from other common forms to <tt>Callable</tt> classes.
*
* @see Executor
* @since 1.5
* @author Doug Lea
* @param <V> the result type of method <tt>call</tt>
*/
public interface Callable<V> {
/**
* Computes a result, or throws an exception if unable to do so.
*
* @return computed result
* @throws Exception if unable to compute a result
*/
V call() throws Exception;
}
把javaDoc上的代码摘抄出来看下~
public interface ArchiveSearcher {
String search(String target);
}
public class App {
ExecutorService executor = ;
ArchiveSearcher searcher = void showSearch(final String target)
throws InterruptedException {
Future<String> future = executor.submit(new Callable<String>() {
public String call() {
return searcher.search(target);
}
});
displayOtherThings(); // do other things while searching
try {
displayText(future.get()); // use future
} catch (ExecutionException ex) {
cleanup();
return;
}
}
}
简单实用介绍:
/**
* 异步任务
*/
public class AsynchronousTask implements Callable<String> { private String data; public AsynchronousTask(String data) {
this.data = data;
} public String call() throws Exception {
try { System.out.println(Thread.currentThread().getName() + "AsynchronousTask start..."); //模拟异步任务的处理
Thread.sleep(1000); System.out.println((Thread.currentThread().getName() + "AsynchronousTask end...")); } catch (Exception ex) { ex.printStackTrace(); }
//返回异步任务的处理结果
return "hello future";
}
}
public class FutureTest {
public static void main(String[] args) throws Exception { ExecutorService executor = Executors.newFixedThreadPool(10); //进行异步任务处理
Future<String> submit = executor.submit(new AsynchronousTask("futire test")); System.out.println(Thread.currentThread().getName() + "FutureTest start");
//这里使用sleep方法表示对其他业务逻辑的处理
//与此同时异步任务也在执行,从而充分利用了等待时间
Thread.sleep(100);
System.out.println(Thread.currentThread().getName() + "FutureTest end"); //submit.get()获取异步执行结果
//如果异步任务call没有执行完成,则依然会等待
System.out.println("数据" + submit.get()); }
}