Java ExecutorServic线程池(异步)

Posted 命运的绯色结局

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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模式是看不出来的。





以上是关于Java ExecutorServic线程池(异步)的主要内容,如果未能解决你的问题,请参考以下文章

线程池ThreadPoolExecutor剖析

Spring Boot中异步线程池@Async详解

浅谈java开启异步线程的几种方法(@Async,AsyncManager,线程池)

SpringBoot自定义异步任务线程池

spring异步线程任务Async,自定义配置线程池,Java

spring异步线程任务Async,自定义配置线程池,Java