zoukankan      html  css  js  c++  java
  • Java ExecutorServic线程池(异步)

     相信大家都在项目中遇到过这样的情况,前台需要快速的显示,后台还需要做一个很大的逻辑。比如:前台点击数据导入按钮,按钮后的服务端执行逻辑A,和逻辑B(执行大量的表数据之间的copy功能),而这时前台不能一直等着,要返回给前台,告诉正在处理中就行了。这里就需要用到异步了。

    点击按钮 -> 逻辑A ->逻辑B(异步) -> 方法结束。

    到底,项目需求明确了,就引入了ExecutorServic线程池。

    Java通过Executors提供四种线程池,分别为:
    newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
    newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
    newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
    newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    /**
     * @author  szy 
     * @version 创建时间:2018-5-20 上午10:25:06
     * 
     */
    public class Testasync {
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            if(task0() == true){
                System.out.println("执行完毕,看异步结果");
            }
            
        }
    
        
        public static void task1(){
            System.out.println("task1 is start");
        }
        
        public static void task2(){
             ExecutorService executor = Executors.newFixedThreadPool(1);
             executor.submit(new Callable(){
    
                @Override
                public Object call() throws Exception {
                    // TODO Auto-generated method stub
                    
                    //增加睡眠时间,便于查看结果
                    /* try {
                            Thread.sleep(10000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }*/
                     
                    //异步提交
                    int sum  = 0;
                    for (int i = 0; i < 10000; i++) {
                         sum += i;
                    }
                    System.out.println("task2执行数据的大量导入或者导出");
                    System.out.println("task2="+sum);
                    System.out.println("task2导入或者导出完成");
                    return null;
                }
                 
                 
             });
            
        }
        
        public static void task3(){
            System.out.println("task3 is start");
            int j = 0;
            while(true) {
                if(j++ > 10) {
                    break;
                }
                System.out.println("------------task3 end-----------");
            }
        }
        
        public static boolean  task0(){
            task1();
            task2();
            task3();
            return true;
        }
    }

    然后看结果:

    task1 is start
    task3 is start
    ------------task3 end-----------
    ------------task3 end-----------
    ------------task3 end-----------
    ------------task3 end-----------
    ------------task3 end-----------
    ------------task3 end-----------
    ------------task3 end-----------
    ------------task3 end-----------
    ------------task3 end-----------
    ------------task3 end-----------
    ------------task3 end-----------
    task2执行数据的大量导入或者导出
    执行完毕,看异步结果
    task2=49995000
    task2导入或者导出完成

    可以看出,task1 和task3先执行了,并且方法在没有等待task2的情况下,直接结束了。

    异步的task2另开了一个线程,自己在执行。和主线程已经无关了。

    不过,这种在eclipse中以deubug模式是看不出来的。

  • 相关阅读:
    黑盒测试用例输入:等价类划分方法
    jar包/class文件如何快速反编译成java文件
    html表格单元格添加斜下框线的方法
    Linux常用命令操作文档
    压力、负载、性能测试工具总结(持续更新。。。)
    压力测试、负载测试及性能测试异同
    Mac os x安装IDEAL及配置JDK和Maven
    RMQ问题总结,标准RMQ算法的实现
    [c++ IO加速]快速输入输出
    [coj 1353 Guessing the Number]kmp,字符串最小表示法
  • 原文地址:https://www.cnblogs.com/sunxun/p/9063059.html
Copyright © 2011-2022 走看看