[Java][Android] 多线程同步-主线程等待全部子线程完毕案例
有時候我們會遇到這種問題:做一個大的事情能夠被分解為做一系列相似的小的事情,而小的事情無非就是參數上有可能不同樣而已!
此時,假設不使用線程,我們勢必會浪費許多的時間來完畢整個大的事情。而使用線程的話將會存在這種問題:
主線程啟動全部子線程并發運行后主線程就直接返回了,導致外部函數判讀整個大的事情完畢了,可是實際上并沒有完畢!
針對以上情況我想我會採用多線程方式運行同一時候解決主線程等待子線程的問題。如圖:
在這里我使用Java進行案例分析。
首先建立一個線程管理類。用于啟動全部子線程和等待全部子線程完畢。在這里不使用休眠一段時間后循環檢測的方式(消耗CUP同一時候消耗時間,全部完畢時間不夠及時等缺點)。而是使用等待臨界值的方式。
ThreadManager.java例如以下:
public class ThreadManager implements NotifyInterface {private final Object mLock = new Object();private int mCount = 0;private int endCount = 0;public ThreadManager(int count) {System.out.println("Manager In.");this.mCount = count;this.addThread();synchronized (mLock) {while (true) {if (checkEnd())break;try {mLock.wait();} catch (InterruptedException e) {e.printStackTrace();}}}System.out.println("Manager Out.");}private void addThread() {System.out.println("Manager addThread().");for (int i = 1; i <= mCount; i++) {ThreadDoThing dThread = new ThreadDoThing(i, "T" + i, this);// StartdThread.start();}}private boolean checkEnd() {boolean bFlag = false;bFlag = endCount >= mCount;System.out.println("Manager checkEnd().Return is:" + bFlag);return bFlag;}@Overridepublic void runEnd() {synchronized (mLock) {++endCount;mLock.notifyAll();}} }此類集成自:NotifyInterface接口,NotifyInterface是用于子線程通知主線程自己已經完畢工作所用類。ThreadManager實例化時將傳入一個int值,用于設置啟動的子線程數,當然這里是為了簡介所以採用的這種方式,實際情況可能更加復雜。
在實例化后 ?進入構造方法,此時將會啟動子線程,啟動后進入循環等待中,當檢測到全部子線程完畢時就退出循環,沒有就將進入臨界值等待,直到通過接口通知主線程完畢時將會通知臨界值一次。此時循環將會運行一次。假設不滿足退出條件將繼續等待臨界值。直到滿足為止。
NotifyInterface接口例如以下:
public interface NotifyInterface {public abstract void runEnd();}測試用的子線程ThreadDoThing.java例如以下: public class ThreadDoThing extends Thread {private NotifyInterface mInterface = null;private int mId = 0;private String mArgs = null;public ThreadDoThing(int id, String args, NotifyInterface iface) {this.mId = id;this.mArgs = args;this.AddInterface(iface);}public void AddInterface(NotifyInterface iface) {this.mInterface = iface;}@Overridepublic void run() {System.out.println("ThreadDoThing Id is:" + this.mId + " Args is:" + this.mArgs);System.out.println(this.mId + ":Doing...");int sleepTime = (int) (Math.random() * 1000);try {Thread.sleep(sleepTime);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(this.mId + ":SleepTime is:" + sleepTime);this.notifyEnd();System.out.println(this.mId + ":Do End.");}private void notifyEnd() {if (this.mInterface != null)this.mInterface.runEnd();System.out.println(this.mId + ":Notify End.");} }
此類繼承自Thread類,可直接重寫Run()方法完畢所做工作。
在工作中,我使用了隨機一個1s內的休眠來取代所做工作的時間。完畢后調用接口通知完畢。
測試方法例如以下:
/*** @param args*/public static void main(String[] args) {// TODO Auto-generated method stubThreadManager manager = new ThreadManager(10);}測試結果: Manager In. Manager addThread(). ThreadDoThing Id is:1 Args is:T1 ThreadDoThing Id is:2 Args is:T2 2:Doing... 1:Doing... ThreadDoThing Id is:3 Args is:T3 ThreadDoThing Id is:4 Args is:T4 3:Doing... 4:Doing... ThreadDoThing Id is:5 Args is:T5 5:Doing... ThreadDoThing Id is:6 Args is:T6 Manager checkEnd().Return is:false ThreadDoThing Id is:8 Args is:T8 ThreadDoThing Id is:7 Args is:T7 8:Doing... ThreadDoThing Id is:9 Args is:T9 9:Doing... 6:Doing... ThreadDoThing Id is:10 Args is:T10 7:Doing... 10:Doing... 3:SleepTime is:111 3:Notify End. 3:Do End. Manager checkEnd().Return is:false 5:SleepTime is:142 5:Notify End. Manager checkEnd().Return is:false 5:Do End. 4:SleepTime is:199 4:Notify End. Manager checkEnd().Return is:false 4:Do End. 7:SleepTime is:342 7:Notify End. Manager checkEnd().Return is:false 7:Do End. 10:SleepTime is:346 10:Notify End. Manager checkEnd().Return is:false 10:Do End. 6:SleepTime is:397 6:Notify End. Manager checkEnd().Return is:false 6:Do End. 9:SleepTime is:468 9:Notify End. Manager checkEnd().Return is:false 9:Do End. 1:SleepTime is:475 1:Notify End. Manager checkEnd().Return is:false 1:Do End. 2:SleepTime is:686 Manager checkEnd().Return is:false 2:Notify End. 2:Do End. 8:SleepTime is:828 8:Notify End. Manager checkEnd().Return is:true 8:Do End. Manager Out.
實際情況可能更加復雜。甚至子線程下還有很多其它的子線程!
詳細情況大家能夠衍生考慮,檢測是否所有返回也能夠有多種方式甚至設置加入一個定時器之類的。
以后有時間畫一個具體點的圖!
轉載于:https://www.cnblogs.com/yangykaifa/p/7154749.html
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的[Java][Android] 多线程同步-主线程等待全部子线程完毕案例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【像程序员一样思考】 读书笔记2
- 下一篇: Duplicate property m