之前有做过一个项目,首页加载出来的时候需要从各个库里查询出数据,一个一个的加载,若用同步调用则所用时间较长,代码简化出来如下;
@Component public class Task { public static Random random =new Random(); public void doTaskOne() throws Exception { System.out.println("开始做任务一"); long start = System.currentTimeMillis(); Thread.sleep(random.nextInt(10000)); long end = System.currentTimeMillis(); System.out.println("完成任务一,耗时:" + (end - start) + "毫秒"); } public void doTaskTwo() throws Exception { System.out.println("开始做任务二"); long start = System.currentTimeMillis(); Thread.sleep(random.nextInt(10000)); long end = System.currentTimeMillis(); System.out.println("完成任务二,耗时:" + (end - start) + "毫秒"); } public void doTaskThree() throws Exception { System.out.println("开始做任务三"); long start = System.currentTimeMillis(); Thread.sleep(random.nextInt(10000)); long end = System.currentTimeMillis(); System.out.println("完成任务三,耗时:" + (end - start) + "毫秒"); } }
@RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = testMain.class) public class test { @Autowired private Task task; @Test public void test() throws Exception { task.doTaskOne(); task.doTaskTwo(); task.doTaskThree(); } }
运行结果如下:
开始做任务一
完成任务一,耗时:3917毫秒
开始做任务二
完成任务二,耗时:4275毫秒
开始做任务三
完成任务三,耗时:1085毫秒
用异步调用:
package com.yf.test; 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 Task { public static Random random =new Random(); @Async public Future<String> doTaskOne() throws Exception { System.out.println("开始做任务一"); long start = System.currentTimeMillis(); Thread.sleep(random.nextInt(10000)); long end = System.currentTimeMillis(); System.out.println("完成任务一,耗时:" + (end - start) + "毫秒"); return new AsyncResult<String>("任务一完成"); } @Async public Future<String> doTaskTwo() throws Exception { System.out.println("开始做任务二"); long start = System.currentTimeMillis(); Thread.sleep(random.nextInt(10000)); long end = System.currentTimeMillis(); System.out.println("完成任务二,耗时:" + (end - start) + "毫秒"); return new AsyncResult<String>("任务二完成"); } @Async public Future<String> doTaskThree() throws Exception { System.out.println("开始做任务三"); long start = System.currentTimeMillis(); Thread.sleep(random.nextInt(10000)); long end = System.currentTimeMillis(); System.out.println("完成任务三,耗时:" + (end - start) + "毫秒"); return new AsyncResult<String>("任务三完成"); } }
package com.yf; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableAsync; @SpringBootApplication @MapperScan("com.yf.dao") @EnableAsync public class testMain { public static void main(String[] args) { SpringApplication.run(testMain.class, args); } }
package com.yf.service; import com.yf.test.Task; import com.yf.testMain; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import java.util.concurrent.Future; @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = testMain.class) public class test { @Autowired private Task task; @Test public void test() throws Exception { long start = System.currentTimeMillis(); Future<String> task1 = task.doTaskOne(); Future<String> task2 = task.doTaskTwo(); Future<String> task3 = task.doTaskThree(); while(true) { if(task1.isDone() && task2.isDone() && task3.isDone()) { // 三个任务都调用完成,退出循环等待 break; } Thread.sleep(1000); } long end = System.currentTimeMillis(); System.out.println("任务全部完成,总耗时:" + (end - start) + "毫秒"); } }
运行结果:
开始做任务一
开始做任务二
开始做任务三
完成任务二,耗时:586毫秒
完成任务三,耗时:1693毫秒
完成任务一,耗时:8670毫秒
任务全部完成,总耗时:9003毫秒
可以看到,通过异步调用,让任务一、二、三并发执行,有效的减少了程序的总运行时间。