前言
我的需求是建立一個新執行緒來執行一些操作,因為如果用同一個執行緒就會導致資源一直被佔據,影響響應效率。
非同步的概念
我的理解:非同步即為在多輛車在多條路上行駛,同步即為多輛車在一條路上行駛。舉個例子:同步:當前如果正在學習c語言的話,那麼我們按照課程安排是不應該學習c++的,只有等這個學期結束學完c語言,下個學期才能學習c++。非同步:離散數學和c語言都是在本學期學習,你不必等c語言學完再學離散數學。
spring boot如何實現非同步
Google搜尋發現存在非同步的註解。
How To Do @Async in Spring
@Async
public void asyncMethodWithVoidReturnType() {
System.out.println("Execute method asynchronously. "
+ Thread.currentThread().getName());
}
總結:1.開啟非同步支援 2.非同步註解使用注意 3.非同步示例
我的非同步踩坑
1.未仔細閱讀two limitations
:Self-invocation — won't work.
測試程式碼如下:
public class AsyncTest {
@Test
public void test1() {
System.out.println("test1的執行緒id為:" + Thread.currentThread().getId());
test2();
}
@Async
public void test2() {
System.out.println("test2的執行緒id為:" + Thread.currentThread().getId());
}
}
效果:兩個都是同一個執行緒,並沒有達到test2是獨立的執行緒的效果
解決方案:將test2放到另一個class中,自我呼叫將不會生效。
2.必須為@Component或@Service註解才能使@Async生效
在將非同步方法放到其他類:
// 第一個類
public class AsyncTest1 {
public void test1() {
System.out.println("test1的執行緒id為:" + Thread.currentThread().getId());
// 新建一個AsyncTest2類,呼叫其非同步方法
AsyncTest2 asyncTest2 = new AsyncTest2();
asyncTest2.test2();
}
}
// 第二個類,定義非同步方法
public class AsyncTest2 {
@Async
public void test2() {
System.out.println("test2的執行緒id為:" +
Thread.currentThread().getId());
}
}
But:結果不隨我願,依然是列印顯示是同一執行緒。
解決:
Spring creates a proxy
for each service
and component
you create using the common annotations. Only those proxies
contain the wanted behavior defined by the method annotations such as the Async
. So, calling those method not via the proxy but by the original naked class would not trigger those behaviors.
簡言之:spring將會給用@Component
和@Service
的類創造代理,只有擁有代理的類才能在使用@Async
時得到想要的結果。