1. 程式人生 > >Furure的簡單介紹和使用

Furure的簡單介紹和使用

bpa cfb idm fat pwm actions ddl effect knn

引子:

技術分享

上圖是兩個系統交互的情況,現在我想將對外系統的調用做成異步實現,那麽就需要考慮兩個問題:

主線程可以得到異步線程的結果,在得到結果之後再進行operation-4 ?主線程如何得到異步線程結果? ?主線程在得到異步線程的結果之前是否可以不等待?

可以使用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());

    }
}

Furure的簡單介紹和使用