SpringBoot 處理非同步呼叫的示例
阿新 • • 發佈:2018-10-31
Springboot中集成了@Async註解,我們在使用的時候直接用就好了.
不需要獲取到返回值
如果只是單純的讓執行緒去非同步執行,不需要返回結果的話,如下示例,直接進行..單執行緒進行的話,至少需要4+3+2=9秒鐘,而我們不考慮執行的結果,只是讓他去執行的話,那麼肯定在他們執行之前執行完成,
後來列印了一下時間,好像就用了4ms.所以,多執行緒非同步還是挺6的....
package com.trs.idap.service; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; /** * Created by Administrator on 2018/10/11. * 描述: * * @author Young * @create 2018-10-11 19:48 */ @Component @Async public class TestAsyncService { @Async public void execAsync1(){ try{ Thread.sleep(2000); System.out.println("甲睡了2000ms"); }catch (Exception e){ e.printStackTrace(); } } @Async public void execAsync2(){ try{ Thread.sleep(4000); System.out.println("乙睡了4000ms"); }catch (Exception e){ e.printStackTrace(); } } @Async public void execAsync3(){ try{ Thread.sleep(3000); System.out.println("丙睡了3000ms"); }catch (Exception e){ e.printStackTrace(); } } }
package com.trs.idap.web.rest.controller; import com.trs.idap.service.TestAsyncService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * Created by Administrator on 2018/10/11. * 描述: * @author Young * @create 2018-10-11 19:46 */ @RequestMapping("/api") @RestController public class TestAsync { @Autowired private TestAsyncService testAsyncService; @RequestMapping("execAsync") public void execAsync(){ testAsyncService.execAsync1();//2s testAsyncService.execAsync2();//4s testAsyncService.execAsync3();//3s System.out.println("我執行結束了"); } }
需要返回值
需要返回值的情況也差不多,可以理解為,一次性把任務分發出去.然後任務各自去執行,這時分發任務後可以返回一個Future,我們可以理解為在飯店做飯給的小票,等飯好了憑小票去拿飯...
等我們做完其他的事情的時候,再來收集這些返回值.通過Future的get()方法,如果該Future對應的方法還沒有執行完,或者沒有結果,此時get()會阻塞在這裡,直到拿到結果值為止....
Futurn還有一個isDone()方法,只是判斷該Future對應的任務有沒有執行完成,和get()大同小異了..看你是想拿到結果,還是想看任務是否執行成功.
所以,我們看下,單執行緒同步的話,至少需要9s+其他處理時間,而現在是最大任務的時間+其他處理時間.此時很明顯的看清楚,9s(所有任務的時間和)是遠遠比最大任務時間要多的多....所以這就是效率....也剛起步,慢慢積累,接收批評.
package com.trs.idap.web.rest.controller;
import com.trs.idap.service.TestAsyncService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
/**
* Created by Administrator on 2018/10/11.
* 描述:
* @author Young
* @create 2018-10-11 19:46
*/
@RequestMapping("/api")
@RestController
public class TestAsync {
@Autowired
private TestAsyncService testAsyncService;
@RequestMapping("execAsync")
public void execAsync() throws ExecutionException, InterruptedException {
long l = System.currentTimeMillis();
Future<String> stringFuture = testAsyncService.execAsync1();//2s
Future<String> stringFuture1 = testAsyncService.execAsync2();//4s
Future<String> stringFuture2 = testAsyncService.execAsync3();//3s
//此時這裡的get方法呼叫了執行緒的阻塞,可以不用isDone進行判斷.
//如果Future還沒有值,執行緒是阻塞的,直到獲取到值時結束
String s = stringFuture.get();
String s1 = stringFuture1.get();
String s2 = stringFuture2.get();
System.out.println("執行結束....."+s+s1+s2);
System.out.println("我執行結束了:"+(System.currentTimeMillis()-l));
}
}
package com.trs.idap.service;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Component;
import java.util.concurrent.Future;
/**
* Created by Administrator on 2018/10/11.
* 描述:
*
* @author Young
* @create 2018-10-11 19:48
*/
@Component
@Async
public class TestAsyncService {
@Async
public Future<String> execAsync1(){
try{
Thread.sleep(2000);
System.out.println("甲睡了2000ms");
return new AsyncResult<String>("甲執行成功了");
}catch (Exception e){
e.printStackTrace();
}
return null;
}
@Async
public Future<String> execAsync2(){
try{
Thread.sleep(4000);
System.out.println("乙睡了4000ms");
return new AsyncResult<String>("乙執行成功了");
}catch (Exception e){
e.printStackTrace();
}
return null;
}
@Async
public Future<String> execAsync3(){
try{
Thread.sleep(3000);
System.out.println("丙睡了3000ms");
return new AsyncResult<String>("丙執行結束了");
}catch (Exception e){
e.printStackTrace();
}
return null;
}
}