java多線程編程--Future模式(基於springboot異步任務)

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


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章