guava 异步编程(listenerFuture monitor RateLimiter)

来源:互联网 发布:网络金融部 编辑:程序博客网 时间:2024/06/05 09:05

runnable和callable都能够开启多线程,但是callable有返回值。通过future取得返回值

public class FutureTest {
    public static void main(String args[]){
        ExecutorService executorService = Executors.newFixedThreadPool(100) ;
        for(int i=0 ;i<100 ;i++) {
            final  String button = " --- "+i+" --- " ;
            Future<String> future = executorService.submit(new Callable<String>() {
                @Override
                public String call() throws Exception {
                    return pushButton(button);
                }
            });




            try {
                System.out.println(future.get()) ;
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
        System.out.println("=================================================") ;
    }


    private static String pushButton(String button){
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return button ;
    }

当你调用Future的get()方法以获得结果时,当前线程就开始阻塞,直接call方法结束返回结果。 

public class FutureTest {
    public static void main(String args[]){
        ExecutorService executorService = Executors.newFixedThreadPool(100) ;
        for(int i=0 ;i<100 ;i++) {
            final  String button = " --- "+i+" --- " ;
            Future<String> future = executorService.submit(new Callable<String>() {
                @Override
                public String call() throws Exception {
                    return pushButton(button);
                }
            }); 

            try {
                System.out.println(future.get()) ;
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
        System.out.println("=================================================") ;
    }


    private static String pushButton(String button){
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return button ;
    }

另,不会阻塞

public class FutureTest {
    public static void main(String args[]){
        ExecutorService executorService = Executors.newFixedThreadPool(100) ;
        ExecutorService executorServiceget = Executors.newFixedThreadPool(100) ;
        for(int i=0 ;i<100 ;i++) {
            final  String button = " --- "+i+" --- " ;
            final Future<String> future = executorService.submit(new Callable<String>() {
                @Override
                public String call() throws Exception {
                    return pushButton(button);
                }
            });


            executorServiceget.execute(new Runnable(){
                public void run(){
                    try {
                        System.out.println(future.get()) ;
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (ExecutionException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
        System.out.println("=================================================") ;
    }   


    private static String pushButton(String button){
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return button ;
    }
}

接口:传统JDK中的Future通过异步的方式计算返回结果:在多线程运算中可能或者可能在没有结束返回结果,Future是运行中的多线程的一个引用句柄,确保在服务执行返回一个Result。
ListenableFuture可以允许你注册回调方法(callbacks),在运算(多线程执行)完成的时候进行调用,  或者在运算(多线程执行)完成后立即执行。这样简单的改进,使得可以明显的支持更多的操作,这样的功能在JDK concurrent中的Future是不支持的。
ListenableFuture 中的基础方法是addListener(Runnable, Executor), 该方法会在多线程运算完的时候,指定的Runnable参数传入的对象会被指定的Executor执行。

添加回调:多数用户喜欢使用 Futures.addCallback(ListenableFuture<V>, FutureCallback<V>, Executor)的方式, 或者 另外一个版本version(译者注:addCallback(ListenableFuture<V> future,FutureCallback<? super V> callback)),默认是采用 MoreExecutors.sameThreadExecutor()线程池, 为了简化使用,Callback采用轻量级的设计.  FutureCallback<V> 中实现了两个方法:
onSuccess(V),在Future成功的时候执行,根据Future结果来判断。
onFailure(Throwable), 在Future失败的时候执行,根据Future结果来判断。

public class ListenableFutureTest {
    public static void main(String args[]){
        ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(100));
        for(int i=0 ;i<100 ;i++) {
            final String str = i+"" ;
            ListenableFuture explosion = service.submit(new Callable() {
                public String call() {
                    return pushBigRedButton(str);
                }
            });
            Futures.addCallback(explosion, new FutureCallback() {
                @Override
                public void onSuccess(Object result) {
                    handlSuccess(result) ;
                }
                @Override
                public void onFailure(Throwable e) {
                    handlFailure(e);
                }
            });


            System.out.println(i) ;
        }
        System.out.println("hello world") ;


    }
    public static void handlSuccess(Object res){
        System.out.println("onsuccess:"+res) ;
    }
    public static void handlFailure(Throwable e){
        System.out.println("onfaulire:"+e) ;
    }
    public static String pushBigRedButton(String str) {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //throw new NullPointerException("ss") ;
        return "success" ;
   }
}

另外:另外, 假如你是从 FutureTask转换而来的, Guava 提供ListenableFutureTask.create(Callable<V>) 和ListenableFutureTask.create(Runnable, V). 和 JDK不同的是, ListenableFutureTask 不能随意被继承(译者注:ListenableFutureTask中的done方法实现了调用listener的操作)。
假如你喜欢抽象的方式来设置future的值,而不是想实现接口中的方法,可以考虑继承抽象类AbstractFuture<V> 或者直接使用 SettableFuture 。
假如你必须将其他API提供的Future转换成 ListenableFuture,你没有别的方法只能采用硬编码的方式JdkFutureAdapters.listenInPoolThread(Future) 来将 Future 转换成 ListenableFuture。尽可能地采用修改原生的代码返回 ListenableFuture会更好一些。


0 0
原创粉丝点击