標籤:bool out manage xtend ddt java pre break 隨機
有時候我們會遇到這種問題:做一個大的事情能夠被分解為做一系列相似的小的事情,而小的事情無非就是參數上有可能不同樣而已!
此時,假設不使用線程,我們勢必會浪費許多的時間來完畢整個大的事情。而使用線程的話將會存在這種問題:
主線程啟動全部子線程並發運行後主線程就直接返回了,導致外部函數判讀整個大的事情完畢了,可是實際上並沒有完畢!
針對以上情況我想我會採用多線程方式運行同一時候解決主線程等待子線程的問題。
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcWl1anVlcg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" >
在這裡我使用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:T1ThreadDoThing Id is:2 Args is:T22:Doing...1:Doing...ThreadDoThing Id is:3 Args is:T3ThreadDoThing Id is:4 Args is:T43:Doing...4:Doing...ThreadDoThing Id is:5 Args is:T55:Doing...ThreadDoThing Id is:6 Args is:T6Manager checkEnd().Return is:falseThreadDoThing Id is:8 Args is:T8ThreadDoThing Id is:7 Args is:T78:Doing...ThreadDoThing Id is:9 Args is:T99:Doing...6:Doing...ThreadDoThing Id is:10 Args is:T107:Doing...10:Doing...3:SleepTime is:1113:Notify End.3:Do End.Manager checkEnd().Return is:false5:SleepTime is:1425:Notify End.Manager checkEnd().Return is:false5:Do End.4:SleepTime is:1994:Notify End.Manager checkEnd().Return is:false4:Do End.7:SleepTime is:3427:Notify End.Manager checkEnd().Return is:false7:Do End.10:SleepTime is:34610:Notify End.Manager checkEnd().Return is:false10:Do End.6:SleepTime is:3976:Notify End.Manager checkEnd().Return is:false6:Do End.9:SleepTime is:4689:Notify End.Manager checkEnd().Return is:false9:Do End.1:SleepTime is:4751:Notify End.Manager checkEnd().Return is:false1:Do End.2:SleepTime is:686Manager checkEnd().Return is:false2:Notify End.2:Do End.8:SleepTime is:8288:Notify End.Manager checkEnd().Return is:true8:Do End.Manager Out.
實際情況可能更加複雜。甚至子線程下還有很多其它的子線程!
詳細情況大家能夠衍生考慮,檢測是否所有返回也能夠有多種方式甚至設定加入一個定時器之類的。
以後有時間畫一個具體點的圖!
[Java][Android] 多線程同步-主線程等待全部子線程完畢案例