• 使用CompletionService解决耗时时间过长任务导致的阻塞问题以及解决ExecutorService.shutdownNow()导致正在执行中的任务被打断,但该任务不会被返回


    使用CompletionService解决耗时时间过长任务导致的阻塞问题

    package com.dwz.executors;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.Callable;
    import java.util.concurrent.CompletionService;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorCompletionService;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Future;
    import java.util.concurrent.TimeUnit;
    import java.util.stream.Collectors;
    import java.util.stream.IntStream;
    /**
     *    有5个任务,其中4个任务执行速度很快,另1个耗时过长,我们不想等待耗时过长的任务执行完成而想立刻拿到4个执行时间较短任务的结果
     */
    public class ComplexExample {
        
        private static Runnable toTask(int i) {
            return () -> {
                try {
                    System.out.printf("The task [%d] will be executed.
    ", i);
                    TimeUnit.SECONDS.sleep(i*5 + 10);
                    System.out.printf("The task [%d] executed done.
    ", i);
                } catch (InterruptedException e) {
                    System.out.printf("The task [%d] be interrupted.
    ", i);
                }
            };
        }
        
        private static void test1() throws InterruptedException, ExecutionException {
            final ExecutorService service = Executors.newFixedThreadPool(5);
            List<Runnable> tasks = IntStream.range(0, 5).boxed().map(ComplexExample::toTask).collect(Collectors.toList());
            
            List<Future<?>> futureList = new ArrayList<>();
            tasks.forEach(r -> {
                futureList.add(service.submit(r));
            });
            
            futureList.get(4).get();
            System.out.println("==========4=========");
            futureList.get(3).get();
            System.out.println("==========3=========");
            futureList.get(2).get();
            System.out.println("==========2=========");
            futureList.get(1).get();
            System.out.println("==========1=========");
            futureList.get(0).get();
            System.out.println("==========0=========");
        }
        
        private static void test2() throws InterruptedException, ExecutionException {
            final ExecutorService service = Executors.newFixedThreadPool(5);
            List<Runnable> tasks = IntStream.range(0, 5).boxed().map(ComplexExample::toTask).collect(Collectors.toList());
            
            final CompletionService<Object> completionService = new ExecutorCompletionService<>(service);
            
            tasks.forEach(r -> {
                completionService.submit(Executors.callable(r));
            });
            
            Future<?> future;
            while((future = completionService.take()) != null) {
                System.out.println(future.get());
            }
        }
    }

    解决ExecutorService.shutdownNow()导致正在执行中的任务被打断,但该任务不会被返回问题

    package com.dwz.executors;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.Callable;
    import java.util.concurrent.CompletionService;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorCompletionService;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Future;
    import java.util.concurrent.TimeUnit;
    import java.util.stream.Collectors;
    import java.util.stream.IntStream;
    /**
     *    有5个任务,其中4个任务执行速度很快,另1个耗时过长,我们不想等待耗时过长的任务执行完成而想立刻拿到4个执行时间较短任务的结果
     */
    public class ComplexExample {
        //出现执行shutdownNow()之后正在执行中的任务被打断,但该任务不会被返回
        private static void test3() throws InterruptedException, ExecutionException {
            final ExecutorService service = Executors.newSingleThreadExecutor();
            List<Runnable> tasks = IntStream.range(0, 5).boxed().map(ComplexExample::toTask).collect(Collectors.toList());
            
            final CompletionService<Object> completionService = new ExecutorCompletionService<>(service);
            
            tasks.forEach(r -> {
                completionService.submit(Executors.callable(r));
            });
                
            TimeUnit.SECONDS.sleep(12);
            List<Runnable> runnables = service.shutdownNow();
            System.out.println(runnables);
        }
        
        
        private static class MyTask implements Callable<Integer> {
            private final Integer value;
            
            private boolean success = false;
            
            MyTask(Integer value) {
                this.value = value;
            }
            
            public boolean isSuccess() {
                return success;
            }
            
            @Override
            public Integer call() throws Exception {
                System.out.printf("The task [%d] will be executed.
    ", this.value);
                TimeUnit.SECONDS.sleep(this.value * 5 + 10);
                System.out.printf("The task [%d] executed done.
    ", this.value);
                success = true;
                return this.value;
            }
            
        }
        
        //解决执行shutdownNow()之后正在执行中的任务被打断,让该任务被返回
        private static void test4() throws InterruptedException, ExecutionException {
            final ExecutorService service = Executors.newSingleThreadExecutor();
            List<Callable<Integer>> tasks = IntStream.range(0, 5).boxed().map(MyTask::new).collect(Collectors.toList());
            final CompletionService<Integer> completionService = new ExecutorCompletionService<>(service);
            tasks.forEach(completionService::submit);
            
            TimeUnit.SECONDS.sleep(12);
            service.shutdownNow();
            
            tasks.stream().filter(callable -> !((MyTask) callable).isSuccess()).forEach(System.out::println);
        }
    }
  • 相关阅读:
    普通百姓如何应对通货膨胀
    经济
    将到来的战略转变:移动 Web 还是移动 Apps?
    ASP.Net 第一天笔记 MVC 控制器与视图数据传递注意事项
    关于阿里云 ETC服务器 端口开放问题
    .net 委托 +lamda表达式
    de4Dot用法 解决 .net程序 reflecter反编译 “索引超出了数组界限”问题
    fastReport.net 初了解
    关于JQuery Ajax 跨域 访问.net WebService
    JQuery AJAX 通过一般处理程序 取列表
  • 原文地址:https://www.cnblogs.com/zheaven/p/13503244.html
Copyright © 2020-2023  润新知