java异步调用处理高并发web应用性能问题

  • Post author:
  • Post category:java

异步调用是处理高并发web应用性能问题的万金油。

同步调用:

@Component
public class Test1 {

    private static Random random = new Random();

    public void taskOne() throws Exception{
        System.out.println("开始做任务1..。");
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long end = System.currentTimeMillis();
        System.out.println("结束做任务1  time:"+(end-start));
    }

    public void taskTwo() throws Exception{
        System.out.println("开始做任务1..。");
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long end = System.currentTimeMillis();
        System.out.println("结束做任务1  time:"+(end-start));
    }

    public void taskThree() throws Exception{
        System.out.println("开始做任务1..。");
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long end = System.currentTimeMillis();
        System.out.println("结束做任务1  time:"+(end-start));
    }


}

任务一、任务二、任务三 顺序的执行完了,换言之 taskOne 、taskTwo、taskThree三个函数是顺序执行的。

上述的同步执行调用虽然顺利的执行完了三个任务,但是可以看到执行时间比较长,若这三个任务本身之间不存在依赖关系,可以并发执行的话,同步调用在执行效率方面就比较差,可以考虑通过异步调用的方式来并发执行。

在Spring boot中,我们只需要通过使用@Async注解就能简单的将原本的同步函数变成异步函数,task类改为如下模式。

package com.example.demo.aa;

import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Component;

import java.util.Random;
import java.util.concurrent.Future;

@Component
public class Test2 {

    private static Random random = new Random();

    @Async
    public Future<String> taskOne() throws Exception{
        System.out.println("开始做任务1..。");
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long end = System.currentTimeMillis();
        System.out.println("结束做任务1  time:"+(end-start));
        return new AsyncResult<>("任务1完成");
    }

    @Async
    public Future<String> taskTwo() throws Exception{
        System.out.println("开始做任务2..。");
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long end = System.currentTimeMillis();
        System.out.println("结束做任务2  time:"+(end-start));
        return new AsyncResult<>("任务2完成");
    }

    @Async
    public Future<String> taskThree() throws Exception{
        System.out.println("开始做任务3..。");
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long end = System.currentTimeMillis();
        System.out.println("结束做任务3  time:"+(end-start));
        return new AsyncResult<>("任务3完成");
    }


}

为了让@Async注解能够生效,还需要在Spring Boot的主程序中配置@EnableAsync,如下所示

@SpringBootApplication
@EnableAsync
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}

 测试

@Test
    void test2() throws Exception{
        long start = System.currentTimeMillis();
        Future<String> taskOne = test2.taskOne();
        Future<String> taskTwo = test2.taskTwo();
        Future<String> taskThree = test2.taskThree();
        while (true){
            if (taskOne.isDone() && taskTwo.isDone() && taskThree.isDone()){
                break;
            }
            Thread.sleep(1000);
        }
        long end = System.currentTimeMillis();
        System.out.println("任务全部完成,总用时:"+(end-start));
    }


开始做任务3..。
开始做任务2..。
开始做任务1..。
结束做任务3  time:3205
结束做任务2  time:4112
结束做任务1  time:6142
任务全部完成,总用时:7023


版权声明:本文为qq_20768305原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。