CompletableFuture.runAsync方法简单应用

453 阅读1分钟
public class Test{
    
    private static  Map<String,String> map = new HashMap<>();

    /**
     * 初始化map数据
     */
     static{
         map.put("1000","上海");
         map.put("2000","北京");
         map.put("3000","广州");
         map.put("4000","深圳");
         map.put("5000","新疆");
         map.put("6000","江苏");
         map.put("7000","浙江");
         map.put("8000","黑龙江");
         map.put("9000","吉林");
         map.put("1001","福建");
         map.put("1103","辽宁");
         map.put("1203","香港");
         map.put("1303","西藏");
     }

    /**
     * 自定义线程池
     */
    private static final ExecutorService pool = new ThreadPoolExecutor(5, 5,
        1L, TimeUnit.MINUTES, new LinkedBlockingQueue<>(30),new DemoThreadFactory(), new ThreadPoolExecutor.AbortPolicy());

    private final ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 5,
        0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(50000), Executors.defaultThreadFactory());

    public static void main(String[] args) {
        testRunAsync();
    }

    /**
     * 应用场景:
     *
     */
    public static void testSupplyAsync(){
        long start = System.currentTimeMillis();
        System.out.println("start:"+start);
        map.forEach((nationalCode, name) -> {
            System.out.println("1.开始处理:"+name);
            // runAsync 不需要返回值
            CompletableFuture.runAsync(()->{
                System.out.println("2.【"+name+"】当前线程为:"+Thread.currentThread().getName());
                //业务代码逻辑
                try {
                    System.out.println("3.开始执行业务代码,处理【"+name+"】数据");
                    Thread.sleep(5* 60 * 1000);
                    //                    Thread.sleep(6 * 1000);
                    System.out.println("4.业务代码执行结束,处理【"+name+"】数据");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }, pool);
        });
        System.out.println("4.cost:"+(System.currentTimeMillis()-start));
    }


    /**
     * 一、自定义线程池测试 异步无返回值
     * 应用场景: 现有一个全国行政区划数据的爬虫任务。自定义线程池大小设为5,即同时爬取5个省的区划代码以及省市数据
     */
    public static void testRunAsync(){
        long start = System.currentTimeMillis();
        System.out.println("start:"+start);
        map.forEach((nationalCode, name) -> {
            System.out.println("1.开始处理:"+name);
            // runAsync 不需要返回值
            CompletableFuture.runAsync(()->{
                System.out.println("2.【"+name+"】当前线程为:"+Thread.currentThread().getName());
                //业务代码逻辑
                try {
                    System.out.println("3.开始执行业务代码,处理【"+name+"】数据");
                    Thread.sleep(5* 60 * 1000);
//                    Thread.sleep(6 * 1000);
                    System.out.println("4.业务代码执行结束,处理【"+name+"】数据");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }, pool);
        });
        System.out.println("4.cost:"+(System.currentTimeMillis()-start));
    }

    public static class DemoThreadFactory implements ThreadFactory {
        private final AtomicInteger poolNumber = new AtomicInteger(1);

        @Override
        public Thread newThread(Runnable r) {
            String name = "division-task-thread-" + poolNumber.getAndIncrement();
            SecurityManager s = System.getSecurityManager();
            ThreadGroup group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();

            Thread thread = new Thread(group, r, name);
//            thread.setDaemon(true);
            return thread;
        }
    }
}