android 的多线程 实现方法,android 线程的高级使用( 二 )


检查核心线程数是否到达最大值 , 否则创建新的核心线程执行任务,是则进行下一步检查任务队列是否已满,否则将任务添加到任务队列中,是则进行下一步检查非核心线程数是否到达最大值,否则创建新的非核心线程执行任务,是则说明这个线程池已经饱和了 , 执行饱和策略 。默认的饱和策略是抛出RejectedExecutionException异常下面手搓一个线程池的实现
//CPU核心数private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();//核心线程数private static final int CORE_POOL_SIZE = CPU_COUNT1;//最大线程数private static final int MAX_POOL_SIZE = CPU_COUNT * 21;//非核心线程闲置的超时时间private static final int KEEP_ALIVE_TIME = 1;//任务队列private static final BlockingQueue sPoolWorkQueue =new LinkedBlockingQueue(128);//线程池private ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE,MAX_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.SECONDS, sPoolWorkQueue);private void fun(){Runnable runnable = new Runnable() {@Overridepublic void run() {//子线程处理耗时操作doSomething();}};poolExecutor.execute(runnable);}这样我们就实现了一个简单的线程池,核心线程数为CPU数量 1,非核心线程数为CPU数量*2 1,非核心线程的闲置时间为1秒,任务队列的大小为128 。
线程池还有具体的好几种分类和相应不同的实现方式,这里不再细说 。
2.3 Handler
有朋友可能会说,你讲的这些都是Java多线程里面的东西 , 能不能整点咱Android特有的?OK,现在进入专业时间 。
Handler是Android提供的一种异步消息处理机制,要学会使用Handler我们首先来了解下消息处理四兄弟:
MessageHandlerMessageQueueLooperHandler可以帮助我们实现在不同的线程之间传递消息,这里的Message就是消息本体,也就是我们想要传递的那个东西 。
Handler在这里扮演的角色是消息处理者,它的主要作用是发送和处理消息 。
MessageQueue是一个消息队列,Handler发送过来的消息会放在这个队列里面,每个线程只会有一个MessageQueue对象 。
Looper是线程中消息队列的管家,它会无限循环运行,每发现MessageQueue中存在一条消息,它就会把消息取出然后发送给Handler 。每一个线程也只能有一个Looper对象 。
好了 , 基本原理已经了解,现在我们来反手搓一个Handler
private static final int FLAG = 1;private Handler mHandler = new Handler(){@Overridepublic void handleMessage(@NonNull Message msg) {if (FLAG == msg.what){//这里已经回到主线程了doSomething();}}};private void fun(){new Thread(new Runnable() {@Overridepublic void run() {//子线程发送消息Message message = new Message();message.what = FLAG;mHandler.sendMessage(message);}}).start();}2.4 AsyncTask
除了Handler以外,谷歌爸爸还给我们提供AsyncTask来进行线程的切换 。AsyncTask是一种轻量级的异步任务,它可以在线程池中执行后台任务,然后把执行的进度和最终结果传递给主线程 。从实现原理上来讲,AsyncTask是对Thread和Handle的再次封装 。
AsyncTask本身是一个抽象的泛型类,有四个亲儿子:
onPreExecute()doInBackground(Params...params)onProgressUpdate(Progress...values)onPostExecute(Result result)最先执行的是方法是onPreExecute()方法,位于主线程中,一般用来做一些准备工作 。
然后执行doInBackground()方法,位于线程池中,用来执行异步任务,params表示异步任务的输入参数 。这个方法需要返回结果给onPostExecute()方法 。
onProgressUpdate()方法在主线程中执行,当后台任务的执行进度发生变化时这个方法会被调用 。
onPostExecute()方法在最后异步任务完成之后会被调用 , 位于主线程中,result参数是后台任务的返回值,即doInBackground()的返回值 。