Future模式是多线程开发中非常常见的一种设计模式。它的核心思想是异步调用。当我们需要调用一个函数方法时。如果这个函数执行很慢,那么我们就要进行等待。但有时候,我们可能并不急着要结果。因此,我们可以让被调用者立即返回,让他在后台慢慢处理这个请求。对于调用者来说,则可以先处理一些其他任务,在真正需要数据的场合再去尝试获取需要的数据。
业务需求,当有数据请求进入,我们分别需要给用户发送短信、系统、短信,这时候三个方法应该异步执行,我们此时使用springboot的异步任务来做
将三个异步方法封装到一个异步类中
package cn.edu.bjfu.component;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Future;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Component;
/**
* 发送消息组件
* <p>Title: SendMessageComponent</p>
* <p>Description: </p>
* @author Tianyu Xiao
* @date 2019年4月25日
*/
@Component
public class SendMessageComponent {
/**
* 发送系统消息
* <p>Description: </p>
* @author Tianyu Xiao
* @throws InterruptedException
* @date 2019年4月25日上午8:03:50
*/
@Async
public Future<Boolean> sendSystemMessage(Integer stationId) throws InterruptedException {
//List<String> userIdList = selectUserIdListByStationId(stationId);
long start = System.currentTimeMillis();
Thread.sleep(1000);//假设系统消息1s
long end = System.currentTimeMillis();
System.out.println("发送系统消息 耗时:" + (end-start) + "毫秒");
return new AsyncResult<Boolean>(true);
}
/**
* 发送邮箱消息
* <p>Description: </p>
* @author Tianyu Xiao
* @date 2019年4月25日上午9:04:53
*/
@Async
public Future<Boolean> sendEmailMessage(Integer stationId) throws InterruptedException {
long start = System.currentTimeMillis();
Thread.sleep(2000);//假设邮箱消息2s
long end = System.currentTimeMillis();
System.out.println("发送邮箱消息 耗时:" + (end-start) + "毫秒");
return new AsyncResult<Boolean>(true);
}
/**
* 发送短信消息
* <p>Description: </p>
* @author Tianyu Xiao
* @date 2019年4月25日上午9:04:43
*/
@Async
public Future<Boolean> sendShortMessage(Integer stationId) throws InterruptedException {
long start = System.currentTimeMillis();
Thread.sleep(3000);//假设短信消息3s
long end = System.currentTimeMillis();
System.out.println("发送短信消息 耗时:" + (end-start) + "毫秒");
return new AsyncResult<Boolean>(true);
}
}
之后去测试类中调用,这个就是模拟前端请求或监控操作
package cn.edu.bjfu.test;
import java.util.concurrent.Future;
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.SpringRunner;
import cn.edu.bjfu.component.SendMessageComponent;
@RunWith(SpringRunner.class)
@SpringBootTest
public class AsyncTest {
@Autowired
private SendMessageComponent sendMessageComponent;
@Test
public void testAsyncTask() throws InterruptedException {
long start = System.currentTimeMillis();
Future<Boolean> f1 = sendMessageComponent.sendSystemMessage(1);
Future<Boolean> f2 = sendMessageComponent.sendEmailMessage(1);
Future<Boolean> f3 = sendMessageComponent.sendShortMessage(1);
//三个方法全部执行完成之后在往下执行
while(!f1.isDone() || !f2.isDone() || !f3.isDone()) {//如果只要有一个没有执行完成,进入循环进行判断
if(f1.isDone() && f2.isDone() && f3.isDone()) {//如果检测到所有的方法都执行完了,跳出循环
break;
}
}
long end = System.currentTimeMillis();
System.out.println("异步总时间:" + (end-start));
}
}
最终的执行结果如下:
发送系统消息 耗时:1015毫秒
发送邮箱消息 耗时:2000毫秒
发送短信消息 耗时:3015毫秒
异步总时间:3031