多執行緒注意事項和獲取子執行緒何時都執行完畢

2022-01-28 22:39:37 字數 1648 閱讀 5986

最近一段時間在整公司專案裡乙個功能的優化,用到了多執行緒處理。期間也是踩了不少的坑,在這裡想說下我遇到的問題和注意事項。以及怎樣知道啟動的那些多執行緒都處理完畢這些問題。

我這裡用的多執行緒,是用了實現runnable介面,這樣的話,要比繼承thread類更加的靈活。畢竟類只能單繼承,但可以多實現。

我實現runnable介面的類,是處理業務的handler類,在spring配置裡面是預設給這些類新增事務的。所以我當時直接在這個類裡面寫了業務**。到測試的時候發現,如果業務方法裡報runtime異常,這個類裡面的一些更新方法居然不回滾,直接提交了。

當時也是試了很多方法,手動給這個類加事務的註解、開闢新事物,都不行。後來查閱資料,發現在runnable實現類裡,是不支援事務的。那我就新寫了乙個類,把主要的業務方法全放到那個類裡,再測試,發現事務可以正常回滾了。

在實現runnable介面的類裡,本來想用spring提供的@autowired註解來自動注入類呢,發現在run方法裡,呼叫注入的類,報空指標。後來明白,實現runnable介面的類不受spring監管,所以spring的一些註解就不能使用了。

解決辦法:

1.可以參考下面這樣寫,可以獲得你想要用的類。

ctx.getbean(你想要獲取的類名.class);

2.那就是在呼叫多執行緒實現類之前,在其他類裡用spring的一些註解,獲得你想要的類,然後通過引數方式,傳到多執行緒實現類裡面。(我是採用的這個方式。)

使用多執行緒,主要就是為了提高程式的執行效率。一般情況下,分配完執行緒,讓那些執行緒去執行就行了,也不需要關心他們都什麼時候執行完畢了。但是有些情況下,知曉那些執行緒都什麼時候執行完畢,確實很有用。

我實現的那個功能就是放在定時器裡面的,知曉定時器什麼時候開始,什麼時候執行完畢,在完畢的時候執行一些發郵件的一些功能,是很有用的。如果是單執行緒,那就直接把那些方法日誌啥的放到最後執行就可以了。

但是開闢了多個執行緒,往往是多執行緒還在執行,主線程不等那些子執行緒,就先自己執行完了,這時候,放到最後執行的那些功能就不行了,因為子執行緒還沒執行完,主線程就把最後的那些「收尾」功能給執行了,肯定不合適。

thread.join方法,可以讓交替執行的執行緒變成順序的執行,但這樣跟單執行緒就沒啥區別了。

後來,我想了乙個辦法。**如下:

//執行緒池

private executorservice threadpool;

//分配執行緒任務

for (int i=0; i<5; i++)

//關閉執行緒池,此時執行的執行緒不會立刻關閉,而是執行緒池不再接受新的執行緒請求了,執行緒執行完會被**掉。

threadpool.shutdown();

while(true)

thread.sleep(1000);//主線程睡眠1秒

}//這裡寫執行完畢的日誌或者最後的「收尾」功能。

這個就是我目前使用的方法。當然,能實現這個功能的方法還有很多,我選的也是比較好實現容易理解,效率算是比較高的一種吧。

以上就是我發現和解決的一些常見的問題。由於能力有限,如有錯誤,敬請諒解。

寫好乙個多執行緒的功能,以上那些注意事項往往根本不夠。最主要的是解決多執行緒之間的衝突,如何避免多執行緒操作導致變數資料的錯亂和引發的資料庫儲存資料的異常等問題。這些是值得推敲和反覆琢磨的,加鎖一般能解決這些問題,但是不合理的加鎖和使用的加鎖方式的不同,可能會導致多執行緒執行起來的效率不盡人意。

多執行緒使用注意事項

在開發過程中經常使用到多執行緒。對ios的多執行緒有很多不解的地方,這裡暫且記錄下來。具體原因有待以後慢慢研究。void scanloop pool release 以asyncudpsocket物件為引數的處理函式,如下所示 void processipscanwithsocket asyncud...

多執行緒程式設計注意事項

1 明確目的,為什麼要使用多執行緒?如果是由於單執行緒讀寫或者網路訪問 例如http訪問網際網路 的瓶頸,可以考慮使用執行緒池。如果是對不同的資源 例如socket連線 進行管理,可以考慮多個執行緒。2 執行緒使用中要注意,如何控制線程的排程和阻塞,例如利用事件的觸發來控制線程的排程和阻塞,也有用訊...

MFC多執行緒程式設計注意事項

視窗類視窗類是乙個結構,其乙個例項代表著乙個視窗型別,與c 中的類的概念非常相近 雖然其表現形式完全不同,c 的類只不過是記憶體布局和其上的操作這個概念的型別 故被稱作為視窗類。視窗是具有裝置操作能力的邏輯概念,即一種能操作裝置 通常是顯示器 的東西。由於視窗是視窗類的例項,就象c 中的乙個類的例項...