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