方法一:輪訓
比如主線程要等子線程在得到變量“val”值的時候開始用“val”的值來進行工作,使用輪訓的方法如下:
public class SubThread extends Thread{ private boolean flag = false;//標志位,用來標識是否應該通知主線程或者其他對象改做事情了 @Override public void run() { super.run(); for(int i=0;i<5;i++){ System.out.println(Thread.currentThread().getName() + " do " + i + "thing"); } flag = true; for(int i=5;i<10;i++){ System.out.println(Thread.currentThread().getName() + " do " + i + "thing"); } } public boolean getFlag(){ return flag; } }public class Test { public static void main(String[] args) { SubThread subThread = new SubThread(); subThread.start(); while(true){ if(subThread.getFlag()){ System.out.println(Thread.currentThread().getName() + " do something ..."); doWork(); break; } } } private static void doWork() { System.out.println(Thread.currentThread().getName() + " do work ..."); } }
可以看出確實實現了效果,但是這種方法太low了,缺點如下:
(1)主線程循環判斷標志位是浪費CPU的表現
(2)如果有另外的線程也需要判斷,那也得在線程中寫一個死循環,代碼太無設計思想可言
,看到這里也許有有人已經想到另外一種方法——回調!
方法二,回調
回調就是調用別的對象的方法時把“自己”傳進去,然后別的對象在某個時候調用“自己的方法”,代碼如下
public interface ThreadCallback { void threadStartLisener(); void threadEndLisener(); }public class SubRunnable implements Runnable { private ThreadCallback mThreadCallback; public SubRunnable(ThreadCallback threadCallback){ this.mThreadCallback = threadCallback; } @Override public void run() { mThreadCallback.threadStartLisener(); for(int i=0;i<5;i++){ System.out.println(Thread.currentThread().getName() + " do something "+i); } mThreadCallback.threadEndLisener(); } }public class ThreadCallbackTest implements ThreadCallback{ private static ThreadCallbackTest mThreadCallbackTest = new ThreadCallbackTest(); public static void main(String[] args) { System.out.println(Thread.currentThread().getName() + " 開始"); new Thread(new SubRunnable(mThreadCallbackTest)).start(); } @Override public void threadStartLisener() { System.out.println(Thread.currentThread().getName() + " 線程,知道SubRunnable線程開始執行任務了"); } @Override public void threadEndLisener() { System.out.println(Thread.currentThread().getName() + " 線程,知道SubRunnable線程任務執行結束了"); } }
輸出結果如下:
main 開始
Thread-0 線程,知道SubRunnable線程開始執行任務了
Thread-0 do something 0
Thread-0 do something 1
Thread-0 do something 2
Thread-0 do something 3
Thread-0 do something 4
Thread-0 線程,知道SubRunnable線程任務執行結束了
發現threadStartLisener()方法和threadEndLisener()方法都是在子線程中執行的。就是說雖然兩個回調方法都成功執行了,但是執行所用的線程確是不正確的。