最近有位朋友问到一个问题:“有一组同时运行的线程,当所有线程执行完毕后,再运行某个功能”的处理方法。正好我们的项目中有相同的功能,整理一下思路与大家交流一下。
一般来说,在android中当一个线程执行完毕,通过handler发送消息的方式来通知其他线程执行接下来的操作(比如通知UI线程更新视图控件)。当有多个线程同时工作时,我们并不知道谁会先结束谁会后结束,这取决于线程中执行的逻辑代码的耗时和cpu的调度。为每个线程都配备一个handler,更增加了业务代码的复杂度。
我们是采用一个整型变量,以二进制的方式作为开关,标识每个线程的完成情况。比如我们有六个线程同时进行,当第一个线程执行结束后,将第一位设成1,第二个线程执行完,将第二位设成1,以此类推。如下图:
每当一个线程完成后,都会通知handler去检查一下这个成员变量,当成员变量中的所以二进制位都变成1,则说明所有线程都执行完毕,具体代码如下:
/**
* Created by caddywang on 2/13/15.
*/
public class TestActivity extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startThreads();
}
private void startThreads(){
for(int i=0; i<6; i++){
final int FINISH_BIT = BIT_VALUES[i];
new Thread(new Runnable() {
@Override
public void run() {
//线程需要执行的具体业务
//do something!
//表示当前线程完成,设置相应结果位
updateResultBit(FINISH_BIT);
}
}).start();
}
}
private synchronized void updateResultBit(int bit){
mBitResult |= bit;
//Debug
Log.e(TAG, "mBitResult = " + Integer.toBinaryString(mBitResult));
//通知handler
mHandler.sendEmptyMessage(0);
}
private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message message){
//63数值的二进制格式为111111,表示六个线程都已经执行完毕
if(mBitResult == 63){
//执行所有线程完成后的工作
Toast.makeText(TestActivity.this, "All Threads is done!", Toast.LENGTH_LONG);
Log.e(TAG, "All Threads is done!");
}
}
};
//用来记录各个线程完成结果情况
private int mBitResult = 0;
//标识六个线程的动作完成的常量值
//对应的二进制数值分别为 000001,000010,000100,001000,010000,100000
private final static int[] BIT_VALUES = {1, 2, 4, 8, 16, 32};
private final static String TAG = "TestActivity";
}