异步Future模式理解及实现案例

来源:互联网 发布:外籍模特知乎 编辑:程序博客网 时间:2024/05/18 02:00


业务中常常会有这样一种场景:多个资源需要同时处理,我们一般会采用以下几种方式

调用线程池的Task类继承Thread或者实现Runnable接口以达到多线程处理的目的;而这种方式却没有线程执行结果的返回值,这样的话往往有需要再做收集结果集,另外处理的方式。

另一种采用异步方式,描述为线程类继承Callable<V>的方式返回异步Future,这种方式会在每个线程返回V结果变量

首先了解Future使用方法:

package java.util.concurrent;/** * 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> {          boolean cancel(boolean mayInterruptIfRunning);          boolean isCancelled();          boolean isDone();          V get() throws InterruptedException, ExecutionException;          V get(long timeout, TimeUnit unit)              throws InterruptedException, ExecutionException, TimeoutException;      }  

例如实例执行求多个资源业务操作之和

import java.util.ArrayList;import java.util.Date;import java.util.List;import java.util.concurrent.Callable;import java.util.concurrent.CountDownLatch;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Future;import java.util.concurrent.TimeUnit;/** * @Description: * @ClassName: FutureTest * @Author: zhubo * @Date: 2016年9月28日 上午9:07:59 * <ModifyLog> * @ModifyContent: * @Author: * @Date: * </ModifyLog> */public class FutureTest {public static void main(String[] args) {List<Resurce> list = new ArrayList<Resurce>();for(int i =0;i<100;i++){list.add(new Resurce(i+1,i+2));}System.out.println("end count:"+test2(list)+" date :"+new Date());}public static Integer test2(List<Resurce> list){System.out.println("begin test2"+new Date());List<Future<Integer>> workers;    ExecutorService executor = Executors.newFixedThreadPool(list.size());        workers = new ArrayList<Future<Integer>>(list.size());        final CountDownLatch latch = new CountDownLatch(list.size());        for(final Resurce resurce :list ){          workers.add(executor.submit(new Callable<Integer>() {                  @Override                  public Integer call() {                  try {                  //模拟业务操作                      Thread.sleep(1000);                  }catch(Exception e){                  System.err.println("this has a Exception ");                  e.printStackTrace();                  }finally{                  latch.countDown();                  }                  return resurce.add();                  }            }));        }        try {            while (true) {                latch.await(10, TimeUnit.SECONDS);//一个较长的时间                if (latch.getCount() != list.size()) {                    break;                }            }        } catch (InterruptedException e) {        System.err.println("this has a InterruptedException ");  e.printStackTrace();        }finally{        //线程池关闭用在此处是不合适的,应用中应该抽取close方法;此处仅为了测试        if(executor!=null){        executor.shutdown();        }        }        Integer count=0;        for (Future<Integer> worker : workers) {            try {                if (worker.isDone() && !worker.isCancelled()) {                Integer a = worker.get(1, TimeUnit.SECONDS);                count =count+a;                }            } catch (Exception e) {             System.err.println("this has a workerException ");            e.printStackTrace();            }       }        return count;    }}




0 0