• invokeAll和CompletionService


    需求场景:服务A依赖于其他三个服务:服务B、服务C、服务D,而服务A的调用方要求服务A在100ms内返回结果。服务A需要在100ms内把已经有结果的服务返回,取消无结果的服务。

    使用ExecutorService.invokeAll()方法,该方法输入是一个Callable任务的集合,返回的是Future集合,Future集合的顺序与输入的任务一样。invokeAll()的超时时限是对这一整组集合来说的。
    该方法会阻塞,当所有任务执行完毕或者超时的时候,方法就会返回,若有未完成的任务,invokeAll()方法中会调用cancel(true)方法来取消任务。我们可以对返回的Future调用isCancelled()方法来看该任务是否已经执行完毕。

        public void testCustomerExecutorException() {
            List<SayHello> tasks = Lists.newArrayList();
            for (int i = 5; i >= 1; i--) {
                tasks.add(new SayHello(i));
            }
    
            List<Future<String>> futures = Lists.newArrayList();
            try {
                futures = fixedExecutorService.invokeAll(tasks, 250, TimeUnit.MILLISECONDS);
            } catch (Exception e) {
                System.out.println("Main: " + e);
            }
    
            for (Future<String> future :futures) {
                try {
                    String s = future.get();
                    System.out.println("get ok: " + s);
                } catch (Exception e) {
                    System.out.println("get error: " + e);
                }
            }
        }
    
        private class SayHello implements Callable<String> {
            private int id;
            public SayHello(int id) {
                this.id = id;
            }
            public String call() throws Exception {
                try {
                    Thread.sleep(id*100);
                } catch (Exception e) {
                    System.out.println(id + "; SayHello: " + e);
                    return "hello " + id;
                }
                return "hello " + id;
            }
        }
    

    CompletionService与invokeAll的不同点在于:
    CompletionService:任务执行完毕马上返回
    invokeAll:需要等全部任务执行完毕或者超时再返回

        public ExecutorService fixedExecutorService = Executors.newFixedThreadPool(5);
        private final BlockingQueue<Future<String>> queue = new LinkedBlockingDeque<Future<String>>(10);
        private final CompletionService<String> completionService = new ExecutorCompletionService<String>(fixedExecutorService, queue);
    
        public void testCustomerExecutorException() {
            for (int i = 5; i >= 1; i--) {
                completionService.submit(new SayHello(i));
            }
    
            for (int i = 0; i < 5; i++)
            {
                try {
                    //谁最先执行完成,直接返回
                    Future<String> f = completionService.take();
                    System.out.println(f.get());
                } catch (Exception e) {
    
                }
            }
        }
    
        private class SayHello implements Callable<String> {
            private int id;
            public SayHello(int id) {
                this.id = id;
            }
            public String call() throws Exception {
                try {
                    Thread.sleep(id*100);
                } catch (Exception e) {
                    return "hello " + id;
                }
                return "hello " + id;
            }
        }
    //输出
    //hello1
    //hello2
    //hello3
    //hello4
    //hello5
    
  • 相关阅读:
    Redhat VNCServer
    Petshop4 的相关文章、下载地址和相关问题
    .Net 2.0 中用 ICallbackEventHandler实现 Ajax无刷新操作
    Silverlight 结合WCF Duplex Service聊天程序出炉
    vsftp的虚拟用户管理
    MySql 内存表使用
    linux 上远程控制
    理解WCF Session笔记
    转载-磁盘管理
    rhel 5 3G以上内存解决方案
  • 原文地址:https://www.cnblogs.com/season-peng/p/8193740.html
Copyright © 2020-2023  润新知