消息机制和线程池

消息机制

android的消息机制主要涉及以下几个类:

  • Handler
  • Looper
    • prepare():对当前线程创建新的looper
    • loop():循环当前线程中的消息
    • quit():停止循环
  • MessageQueue
    • enqueueMessage():handler插入消息到消息队列中
    • next():looper从消息队列中获取消息
  • ThreadLocal:这个是在Looper里维护的

ThreadLocal有两种使用场景:

  1. 当作用域为线程,并且不同作用域需要有不同的数据副本的时候;
  2. 在复杂逻辑下对象需要不断传递的情况。

主线程已经被做成了是Looper的线程,所以不用像自己的线程那样做特殊处理。在ActivityThread里的main()方法中:

创建自己的Looper 以及一个完整的实例:

package com.pan.learn;/*
 * Copyright (C) 2016 Baidu, Inc. All Rights Reserved.
 */

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

/**
 * Created by panhongchao on 16/2/12.
 */
public class HandlerActivity extends Activity {
    public Handler mHandler;

    private Handler handler1 = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            Toast.makeText(HandlerActivity.this, "handler1: " + Looper.myLooper(), Toast.LENGTH_SHORT).show();
        }
    };

    private Handler handler2 = new Handler(createLooper("-sub-"), new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            Toast.makeText(HandlerActivity.this, "handler2: " + Looper.myLooper(), Toast.LENGTH_SHORT).show();
            return true;
        }
    });

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Button button = new Button(this);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Message message = Message.obtain();
//                handler1.sendMessage(message);

                handler2.sendMessage(message);
            }
        });

        new MThread().start();

        setContentView(button);
    }

    public class MThread extends Thread {

        @Override
        public void run() {
            Looper.prepare();
            mHandler = new Handler() {
                public void handleMessage(Message msg) {
                    Toast.makeText(HandlerActivity.this, "sub handler: " + Looper.myLooper(), Toast.LENGTH_SHORT)
                            .show();
                }
            };
            Looper.loop();
        }
    }

    private Looper createLooper(String threadName) {
        final BlockingItem<Looper> bl = new BlockingItem<Looper>();
        new Thread(threadName) {
            @Override
            public void run() {
                Looper.prepare();
                Looper l = Looper.myLooper();
                bl.put(l);
                Looper.loop();
            }
        }.start();
        try {
            return bl.take();
        } catch (Exception e) {
            return Looper.getMainLooper();
        }
    }
}

---------------------------------------------

/*
 * Copyright (C) 2016 Baidu, Inc. All Rights Reserved.
 */
package com.pan.learn;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 一个线程安全的对象包装器。一般在多线程并发操作一个对象时使用。
 * <p/>
 * 注:BlockingItem使用了可重入锁ReentrantLock来处理资源的并发,默认是非公平的(先take的不一定先拿到)。
 *
 * @param <T> 需要被包装的对象类型
 */
public class BlockingItem<T> {
    final Lock lock = new ReentrantLock();
    final Condition notEmpty = lock.newCondition();

    private volatile T item;

    public void put(T x) {
        lock.lock();
        try {
            item = x;
            if (x != null) {
                notEmpty.signal();
            }
        } finally {
            lock.unlock();
        }
    }

    public T take() throws InterruptedException {
        lock.lock();
        try {
            while (item == null) {
                notEmpty.await();
            }
            T t = item;
            item = null;
            return t;
        } finally {
            lock.unlock();
        }
    }

    public T tryTake(long waitMs) throws InterruptedException {
        lock.lock();
        try {
            while (item == null) {
                if (!notEmpty.await(waitMs, TimeUnit.MILLISECONDS)) {
                    return null;
                }
            }
            T t = item;
            item = null;
            return t;
        } finally {
            lock.unlock();
        }
    }

    public T peek() {
        return item;
    }
}

线程和线程池

AsyncTask

  • onPreExecute()
  • doInBackground()
  • onProgressUpdate()
  • onPostExecute()

Task实例和execute()的创建和执行必须在主线程(错误)。----这个在子线程也是可以的。

小于1.6 AsyncTask是串行执行的;
大于等于1.6&&小于3.0 AsyncTask是并行执行的;
大于等于3.0 同时提供了串行并行的方法。

串行:execute
并行:executeOnExecutor
串行的实现是在内部实现了一个SerialExecutor,把task在这里进行排队。
真正的执行是在由THREAD_POOL_EXECUTOR线程池去执行的。
还有个InternalHandler,它确保了线程能够从非主线程切回到主线程上去。【看代码它已经写死了线程为主线程,所以就保证了创建task不一定需要在主线程了,除非onPreExecute中有UI上的操作】

private static class InternalHandler extends Handler {
    public InternalHandler() {
        super(Looper.getMainLooper());
    }

    @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
    @Override
    public void handleMessage(Message msg) {
        AsyncTaskResult<?> result = (AsyncTaskResult<?>) msg.obj;
        switch (msg.what) {
            case MESSAGE_POST_RESULT:
                // There is only one result
                result.mTask.finish(result.mData[0]);
                break;
            case MESSAGE_POST_PROGRESS:
                result.mTask.onProgressUpdate(result.mData);
                break;
        }
    }
}

HandlerThread
一个在创建时已经有looper的thread。

IntentService
IntentService和Service的区别在于它在内部开启了一个子的线程,从而从UI线程独立出来了。

@Override
public void onCreate() {
    // TODO: It would be nice to have an option to hold a partial wakelock
    // during processing, and to have a static startService(Context, Intent)
    // method that would launch the service & hand off a wakelock.

    super.onCreate();
    HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
    thread.start();

    mServiceLooper = thread.getLooper();
    mServiceHandler = new ServiceHandler(mServiceLooper);
}

依赖HandlerThread建立了一个子线程,在子线程调用onHandleIntent完成具体的业务逻辑。

java的并发框架(java executor framework) java并发框架类

  • Executor:Executor接口是Executor框架中最基础的部分,定义了一个用于执行Runnable的execute方法
  • ExecutorService:ExecutorService接口继承自Executor接口,定义了终止、提交任务、跟踪任务返回结果等方法。
  • Callable:类似于Runnable的任务,区别在于它接受泛型,并且执行完成之后能够返回执行的结果。
  • Future:异步任务的执行结果
  • FutureTask:Futrue的具体实现类
  • ThreadPoolExecutor:实现了ExecutorService接口的并且有线池的实现类。
  • Executors:Executors中所定义的 Executor、ExecutorService、ScheduledExecutorService、ThreadFactory 和 Callable 类的工厂和实用方法。

线程池的处理流程是这样的:

  1. 首先线程池判断基本线程池是否已满?没满,创建一个工作线程来执行任务。满了,则进入下个流程。
  2. 其次线程池判断工作队列是否已满?没满,则将新提交的任务存储在工作队列里。满了,则进入下个流程。
  3. 最后线程池判断整个线程池是否已满?没满,则创建一个新的工作线程来执行任务,满了,则交给饱和策略来处理这个任务。

results matching ""

    No results matching ""