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管理变量,则每一个使用该变量的线程都获得该变量的副本,副本之间相互独立,这样每一个线程都可以随意修改自己的变量副本,而不会对其他线程产生影响。