关于Android中使用Handler部分的同步,首先简单说一下线程同步的问题吧,什么是同步??
同步就是互斥+顺序,也就是一个线程的执行依赖于另外一个线程执行的结果
引用一个今天在查看Camera相关代码的时候,遇到的一个Handler使用的同步问题:
某个方法的执行依赖于Handler中的执行的结果:
package com.example.androidtestdemo;
import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
int resultCount = 0;
Handler mCameraHandler = new Handler(){
public void handleMessage(android.os.Message msg) {
Log.i(TAG, "MSG:"+msg.what);
switch (msg.what) {
case 1:
try {
Log.i(TAG, "start sleep 5s");
Thread.sleep(5000);
Log.i(TAG, "end sleep 5s");
resultCount = 10;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
case 2:
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.i(TAG, "========2");
break;
default:
break;
}
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
Log.i(TAG, "resultCount1:"+resultCount);
check1();
// check2();
Log.i(TAG, "resultCount2:"+resultCount);
}
}).start();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void check1(){
mCameraHandler.sendEmptyMessage(1);
waitDone();
}
public void check2(){
mCameraHandler.sendEmptyMessage(2);
waitDone();
}
static int count = 0;
private boolean waitDone() {
final Object waitDoneLock = new Object();
Log.i(TAG, "waitDownLock:"+waitDoneLock.toString());
final Runnable unlockRunnable = new Runnable() {
@Override
public void run() {
synchronized (waitDoneLock) {
Log.i(TAG, "start notify"+System.currentTimeMillis());
waitDoneLock.notifyAll();
Log.i(TAG, "end notify"+System.currentTimeMillis());
}
}
};
synchronized (waitDoneLock) {
count++;
mCameraHandler.post(unlockRunnable);
try {
Log.i(TAG, "start wait:"+System.currentTimeMillis());
waitDoneLock.wait();
Log.i(TAG, "end wait:"+System.currentTimeMillis());
Log.i(TAG, "resultCount3:"+count);
} catch (InterruptedException ex) {
Log.v(TAG, "waitDone interrupted");
return false;
}
}
return true;
}
}
其实刚开始在看到这个waitDone的时候,完全处于一种懵逼状态,一看没看懂。什么个鸟意思,每个方法执行的时候都需要去重新new出来一个新的锁,谈不上线程同步锁,但是多出来的是wait和notify的方法。也很是纳闷,后来简单搜了一下关于这个mHandler.post,原来这个方法是在mHandler执行完线程中的任务后,再紧接着去执行的,也就是handler.post这个方法的执行是sendEmptyMessage执行之后。
所以这个notify也就是在mHandler之后去等待线程中的任务
举个最简单的例子:
一个全局变量,他的计算都是在Handler中的,但是使用是在Handler以外的方法中去使用,那么这个时候就可以去使用wait和notify的形式去进行同步,这样足以确保是计算结束以后执行操作。