Android中多线程同步的方法很多:
1、最常用的 Handler机制,我们在工作线程中完成耗时的操作,然后把结果通过Handler + message 的方式抛给UI线程进行处理,还可以他通过Handler的post(), postDelay(),传递一个Runnable到UI线程中进行处理
2、activity的runOnUiThread(Runnable action)把action传递给UI线程处理我们查看源码
/**
* Runs the specified action on the UI thread. If the current thread is the UI
* thread, then the action is executed immediately. If the current thread is
* not the UI thread, the action is posted to the event queue of the UI thread.
*
* @param action the action to run on the UI thread
*/
public final void runOnUiThread(Runnable action) {
if (Thread.currentThread() != mUiThread) {
mHandler.post(action);
} else {
action.run();
}
}
发现runOnUiThread其实就是调的UI线程的Handler的post方法实现的
3、View 的post(), postDelay()
/**
* <p>Causes the Runnable to be added to the message queue.
* The runnable will be run on the user interface thread.</p>
*
* @param action The Runnable that will be executed.
*
* @return Returns true if the Runnable was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting.
*
* @see #postDelayed
* @see #removeCallbacks
*/
public boolean post(Runnable action) {
final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
return attachInfo.mHandler.post(action);
}
// Postpone the runnable until we know on which thread it needs to run.
// Assume that the runnable will be successfully placed after attach.
getRunQueue().post(action);
return true;
}
/**
* <p>Causes the Runnable to be added to the message queue, to be run
* after the specified amount of time elapses.
* The runnable will be run on the user interface thread.</p>
*
* @param action The Runnable that will be executed.
* @param delayMillis The delay (in milliseconds) until the Runnable
* will be executed.
*
* @return true if the Runnable was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting. Note that a
* result of true does not mean the Runnable will be processed --
* if the looper is quit before the delivery time of the message
* occurs then the message will be dropped.
*
* @see #post
* @see #removeCallbacks
*/
public boolean postDelayed(Runnable action, long delayMillis) {
final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
return attachInfo.mHandler.postDelayed(action, delayMillis);
}
// Postpone the runnable until we know on which thread it needs to run.
// Assume that the runnable will be successfully placed after attach.
getRunQueue().postDelayed(action, delayMillis);
return true;
}
可以知道最终也是调用的UI线程的Handler来post了一个Runnable对象到UI线程中进行处理;
4、AsyncTask 方法,是Android 为我们提供的一个很方便的实现单线程模型的辅助类,把耗时的操作放在工作线程中处理
/**
* Override this method to perform a computation on a background thread. The
* specified parameters are the parameters passed to {@link #execute}
* by the caller of this task.
*
* This method can call {@link #publishProgress} to publish updates
* on the UI thread.
*
* @param params The parameters of the task.
*
* @return A result, defined by the subclass of this task.
*
* @see #onPreExecute()
* @see #onPostExecute
* @see #publishProgress
*/
@WorkerThread
protected abstract Result doInBackground(Params... params);
执行结果抛给UI线程处理
/**
* <p>Runs on the UI thread after {@link #doInBackground}. The
* specified result is the value returned by {@link #doInBackground}.</p>
*
* <p>This method won't be invoked if the task was cancelled.</p>
*
* @param result The result of the operation computed by {@link #doInBackground}.
*
* @see #onPreExecute
* @see #doInBackground
* @see #onCancelled(Object)
*/
@SuppressWarnings({"UnusedDeclaration"})
@MainThread
protected void onPostExecute(Result result) {
}
还提供给了我们预处理方法,及更新进度的方法,这些都是在UI主线程中进行操作
/**
* Runs on the UI thread before {@link #doInBackground}.
*
* @see #onPostExecute
* @see #doInBackground
*/
@MainThread
protected void onPreExecute() {
}/**
* Runs on the UI thread after {@link #publishProgress} is invoked.
* The specified values are the values passed to {@link #publishProgress}.
*
* @param values The values indicating progress.
*
* @see #publishProgress
* @see #doInBackground
*/
@SuppressWarnings({"UnusedDeclaration"})
@MainThread
protected void onProgressUpdate(Progress... values) {
}
5、加锁同步:
Synchronized同步锁同步,这个可同步代码段或同步方法
ReenTrantLock 重入锁同步
6、volatile关键字同步
volatile关键字为域变量的访问提供了一种免锁机制,使用volatile修饰域相当于告诉虚拟机该域可能会被其他线程更新,每次使用该域就要重新计算,而不是使用寄存器中的值
volatile不会提供任何原子操作,它也不能用来修饰final类型的变量
7、wait() notify()实现同步,在线程1中对某一对象调用wait(),线程1进入等待池,让出对象锁,在线程2中对同一对象调用notify(),线程1重新运行
private static class Thread2 implements Runnable {
@Override
public void run() {
System.out.println("*** this is thread2");
synchronized(Thread1.class) {
Thread1.class.notify();
}
try {
System.out.println("*** this is thread2 sleep");
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("*** this is thread2 going");
System.out.println("*** this is thread2 over");
}
}
private static class Thread1 implements Runnable {
@Override
public void run() {
System.out.println("*** this is thread1");
synchronized(Thread1.class){
try {
System.out.println("*** this is thread1 wait");
Thread1.class.wait(1, 1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("*** this is thread1 going");
System.out.println("*** this is thread1 over");
}
}
8、ThreadLocal局部变量同步,使用ThreadLocal管理变量,则每一个使用该变量的线程都获得该变量的副本,副本之间相互独立,这样每一个线程都可以随意修改自己的变量副本,而不会对其他线程产生影响。