From a1b587ea7af32a9b94315f99ece6784a0015a85d Mon Sep 17 00:00:00 2001 From: Omooo <869759698@qq.com> Date: Tue, 26 Mar 2019 21:48:19 +0800 Subject: [PATCH] =?UTF-8?q?finsh=20ThreadPool=E3=80=81AsyncTask?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 16 +- blogs/Android/AsyncTask.md | 227 ++++++++++++++++++++++-- blogs/Android/Handler 消息机制.md | 2 +- blogs/Java/并发/线程、线程池.md | 66 +++++++ images/Java/线程池.png | Bin 0 -> 30656 bytes 5 files changed, 297 insertions(+), 14 deletions(-) create mode 100644 images/Java/线程池.png diff --git a/README.md b/README.md index 7e41097..66f27ea 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,10 @@ Android Notes 11. [热修复](https://github.com/Omooo/Android-Notes/blob/master/blogs/Android/%E7%83%AD%E4%BF%AE%E5%A4%8D.md) 12. [事件分发机制](https://github.com/Omooo/Android-Notes/blob/master/blogs/Android/%E4%BA%8B%E4%BB%B6%E5%88%86%E5%8F%91%E6%9C%BA%E5%88%B6.md) 13. [Handler 消息循环机制](https://github.com/Omooo/Android-Notes/blob/master/blogs/Android/Handler%20%E6%B6%88%E6%81%AF%E6%9C%BA%E5%88%B6.md) +14. [AsyncTask 源码分析](https://github.com/Omooo/Android-Notes/blob/master/blogs/Android/AsyncTask.md) +15. [HandlerThread 源码分析]() +16. [IntentService 源码分析](https://github.com/Omooo/Android-Notes/blob/master/blogs/Android/IntentService.md) +17. [View 工作原理](https://github.com/Omooo/Android-Notes/blob/master/blogs/Android/View%20%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86.md) ##### 性能优化 @@ -62,7 +66,7 @@ Android Notes [电量优化](https://github.com/Omooo/Android-Notes/blob/master/blogs/Android/%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96/%E7%94%B5%E9%87%8F%E4%BC%98%E5%8C%96.md) -#### Java +#### Java 基础 [final 你需要知道的一切](https://github.com/Omooo/Android-Notes/blob/master/blogs/Java/final.md) @@ -76,10 +80,20 @@ Android Notes [异常 你需要知道的一切](https://github.com/Omooo/Android-Notes/blob/master/blogs/Java/%E5%BC%82%E5%B8%B8.md) +[BIO、NIO、AIO](https://github.com/Omooo/Android-Notes/blob/master/blogs/Java/BIO%E3%80%81NIO%E3%80%81AIO.md) + [UncaughtExceptionHandler](https://github.com/Omooo/Android-Notes/blob/master/blogs/Java/UncaughtExceptionHandler.md) [Java 5 - Java 10 新特性总结](https://github.com/Omooo/Android-Notes/tree/master/blogs/Java/Java%205%20-%20Java%2010%20%E6%96%B0%E7%89%B9%E6%80%A7) +#### Java 并发 + +[线程、线程池](https://github.com/Omooo/Android-Notes/blob/master/blogs/Java/%E5%B9%B6%E5%8F%91/%E7%BA%BF%E7%A8%8B%E3%80%81%E7%BA%BF%E7%A8%8B%E6%B1%A0.md) + +[线程生命周期](https://github.com/Omooo/Android-Notes/blob/master/blogs/Java/%E5%B9%B6%E5%8F%91/Java%20%E7%BA%BF%E7%A8%8B%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F.md) + +[并发编程的万能钥匙 - 管程 ( Monitor )](https://github.com/Omooo/Android-Notes/blob/master/blogs/Java/%E5%B9%B6%E5%8F%91/%E7%AE%A1%E7%A8%8B(Monitor).md) + #### JVM [一篇文章学完 JVM 重点知识](https://github.com/Omooo/Android-Notes/blob/master/blogs/JVM/JVM.md) diff --git a/blogs/Android/AsyncTask.md b/blogs/Android/AsyncTask.md index 0484e16..5967b38 100644 --- a/blogs/Android/AsyncTask.md +++ b/blogs/Android/AsyncTask.md @@ -4,22 +4,225 @@ AsyncTask #### 目录 -1. 思维导图 -2. 概述 -3. 具体使用 -4. 源码分析 -5. 参考 +1. 前言 +2. 源码分析 -#### 思维导图 +#### 前言 -#### 概述 +AsyncTask 是一个轻量级的异步任务类、抽象泛型类。现在基本上没人会用到它了,但是学习一下源码还是很有必要的。很早之前就阅读 AsyncTask 源码了,当时看的迷迷糊糊的,很大一部分原因是我对线程池以及 Future、Callable 不熟悉,所以在看源码之前,一定要熟悉这一块的知识,不熟悉的可以先看看 [线程、线程池](https://github.com/Omooo/Android-Notes/blob/master/blogs/Java/%E5%B9%B6%E5%8F%91/%E7%BA%BF%E7%A8%8B%E3%80%81%E7%BA%BF%E7%A8%8B%E6%B1%A0.md)。 -AsyncTask 是一个轻量级的异步任务类、抽象泛型类。 - -#### 具体使用 +在熟悉了 Callable、FutureTask、ArrayDeque 之后,在看 AsyncTask,简直不要太简单。 #### 源码分析 -#### 参考 +首先看一下 AsyncTask 的成员变量: + +```java + //串行的任务执行器 + public static final Executor SERIAL_EXECUTOR = new SerialExecutor(); + + private static final int MESSAGE_POST_RESULT = 0x1; + private static final int MESSAGE_POST_PROGRESS = 0x2; + + private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR; + private static InternalHandler sHandler; + + //任务队列,是 Callable 类型 + private final WorkerRunnable mWorker; + private final FutureTask mFuture; +``` + +那 SerialExecutor 到底做了什么呢? + +```java + private static class SerialExecutor implements Executor { + final ArrayDeque mTasks = new ArrayDeque(); + Runnable mActive; + + public synchronized void execute(final Runnable r) { + //把一个任务插入到队列尾部 + mTasks.offer(new Runnable() { + public void run() { + try { + r.run(); + } finally { + //当这个任务执行完毕后,再取任务队列的头部执行 + scheduleNext(); + } + } + }); + if (mActive == null) { + scheduleNext(); + } + } + + protected synchronized void scheduleNext() { + //取任务队列的头部,然后删除 + if ((mActive = mTasks.poll()) != null) { + THREAD_POOL_EXECUTOR.execute(mActive); + } + } + } +``` + +所以这里就明白了,默认任务是串行执行的,越早放入的任务越早执行,同时当这个任务执行完毕之后,就会再从头部去取任务,也就达到了循环执行任务的目的了。 + +然后就是 AsyncTask 的构造方法: + +```java + public AsyncTask() { + this((Looper) null); + } + public AsyncTask(@Nullable Looper callbackLooper) { + //获取主线程 Handler + //用于在任务执行完和任务执行过程回调函数更新进度 + mHandler = callbackLooper == null || callbackLooper == Looper.getMainLooper() + ? getMainHandler() + : new Handler(callbackLooper); + + mWorker = new WorkerRunnable() { + public Result call() throws Exception { + mTaskInvoked.set(true); + Result result = null; + try { + Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); + //重写的后台操作方法 + result = doInBackground(mParams); + Binder.flushPendingCommands(); + } catch (Throwable tr) { + mCancelled.set(true); + throw tr; + } finally { + postResult(result); + } + return result; + } + }; + + mFuture = new FutureTask(mWorker) { + @Override + protected void done() { + try { + postResultIfNotInvoked(get()); + } catch (InterruptedException e) { + android.util.Log.w(LOG_TAG, e); + } catch (ExecutionException e) { + throw new RuntimeException("An error occurred while executing doInBackground()", + e.getCause()); + } catch (CancellationException e) { + postResultIfNotInvoked(null); + } + } + }; + } +``` + +接下来就是 AsyncTask#execute() 方法: + +```java + //调用这个方法,默认是 sDefaultExecutor,也就是上面的 SerialExecutor,即串行执行 + public final AsyncTask execute(Params... params) { + return executeOnExecutor(sDefaultExecutor, params); + } + //当然,AsyncTask 也支持并行执行,传入 AsyncTask.THREAD_POOL_EXECUTOR + public final AsyncTask executeOnExecutor(Executor exec, + Params... params) { + if (mStatus != Status.PENDING) { + switch (mStatus) { + case RUNNING: + throw new IllegalStateException("Cannot execute task:" + + " the task is already running."); + case FINISHED: + throw new IllegalStateException("Cannot execute task:" + + " the task has already been executed " + + "(a task can be executed only once)"); + } + } + + mStatus = Status.RUNNING; + //重写的第一个方法 + onPreExecute(); + + mWorker.mParams = params; + //mFuture 是对任务队列(mWorker)的包装,可以通过 mFuture.get() 获得执行结果 + exec.execute(mFuture); + + return this; + } +``` + +我们知道,AsyncTask 的 execute 必须要在主线程中去执行,所以 onPreExecute() 也是在主线程中运行的。 + +再回头看看 AsyncTask 在执行完任务之后调用的 postResult 方法: + +```java + private Result postResult(Result result) { + @SuppressWarnings("unchecked") + Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT, + new AsyncTaskResult(this, result)); + message.sendToTarget(); + return result; + } + + protected final void publishProgress(Progress... values) { + if (!isCancelled()) { + getHandler().obtainMessage(MESSAGE_POST_PROGRESS, + new AsyncTaskResult(this, values)).sendToTarget(); + } + } + + //任务执行过程中和执行完毕的包装类 + //mData 即执行的中间数据或执行结果 + //mTask 即当前 AsyncTask,用于调用 finsh 和 publishProgress 方法 + private static class AsyncTaskResult { + final AsyncTask mTask; + final Data[] mData; + + AsyncTaskResult(AsyncTask task, Data... data) { + mTask = task; + mData = data; + } + } + + private static class InternalHandler extends Handler { + public InternalHandler(Looper looper) { + super(looper); + } + + @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"}) + @Override + public void handleMessage(Message msg) { + AsyncTaskResult result = (AsyncTaskResult) msg.obj; + switch (msg.what) { + case MESSAGE_POST_RESULT: + // 任务执行完毕回调 + result.mTask.finish(result.mData[0]); + break; + case MESSAGE_POST_PROGRESS: + // 任务执行过程中产生中间结果回调 + // 重写的更新进度方法 + result.mTask.onProgressUpdate(result.mData); + break; + } + } + } + + private void finish(Result result) { + if (isCancelled()) { + onCancelled(result); + } else { + //重写的回调结果方法 + onPostExecute(result); + } + mStatus = Status.FINISHED; + } + + +``` + +##### 总结 + +首先说默认实现,即单线程线程池(SerialExecutor),它是系统全局的,也就是说每次实例化一个 AsyncTask 去执行任务的时候,都是先把任务添加到 ArrayDeque 队列尾部,然后等待上一个任务执行完毕之后,在去队列头部拿一个任务继续执行。 +任务都被封装成一个 Callable,即需要获取任务执行结果,执行的时候即是调用 doInBackground 方法,关于 onPostExecute 和 onProgressUpdate 即是在执行完毕和执行过程中通过 Handler 发消息来调用。 +AsyncTask 支持多线程并发,需要使用 executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR),传入 AsyncTask 中静态的线程池而已。 -[译文:Android中糟糕的AsyncTask](https://droidyue.com/blog/2014/11/08/bad-smell-of-asynctask-in-android/) \ No newline at end of file diff --git a/blogs/Android/Handler 消息机制.md b/blogs/Android/Handler 消息机制.md index 2b79d27..afaeec9 100644 --- a/blogs/Android/Handler 消息机制.md +++ b/blogs/Android/Handler 消息机制.md @@ -30,7 +30,7 @@ Android 应用是通过消息驱动运行的,在 Android 中一切皆消息, #### 基本使用 -基本使用不用多说,这里说一点就是尽量用第一种写法,第二种写法存在内存泄露。 +基本使用不用多说,有以下两种,但是都存在内存泄漏的情况,如何避免呢?可以通过静态内部类 + 弱引用来避免,文末常见问题汇总会有示例。 ```java private Handler mHandler = new Handler(new Handler.Callback() { diff --git a/blogs/Java/并发/线程、线程池.md b/blogs/Java/并发/线程、线程池.md index f7a5e39..76bd1a9 100644 --- a/blogs/Java/并发/线程、线程池.md +++ b/blogs/Java/并发/线程、线程池.md @@ -17,6 +17,8 @@ Java 线程、线程池 #### 前言 +线程、线程池这一块,如果牵扯到并发安全,那估计就不是一篇文章能写完的了,所以本篇文章侧重复习一下基础知识,同时学习了一下 Callable 和 Future,这也是为了阅读 AsyncTask 源码打下基础。又正赶上极客时间开了《并发编程实战》一栏,补充了线程生命周期、多线程线程分配数量策略等相关知识。 + #### 线程 ##### 线程的创建 @@ -132,6 +134,8 @@ public interface Future { ##### ThreadPoolExecutor +当你看到这里,我还是推荐你看:[Java并发编程:线程池的使用](https://www.cnblogs.com/dolphin0520/p/3932921.html) 这篇文章,这篇文章是我见过讲的最好的最仔细的!!! + ThreadPoolExecutor 类是线程池中最核心的一个类,它提供了四个构造方法: ```java @@ -207,7 +211,69 @@ public ThreadPoolExecutor(int corePoolSize, 由调度线程处理该任务。 +类继承关系如下: + +![](https://i.loli.net/2019/03/26/5c9981d2230e8.png) + +这里我就拿参考文章中的示例跑了一遍: + +```java +public class ThreadDemo { + public static void main(String[] args) throws ExecutionException, InterruptedException { + ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, + 2, TimeUnit.SECONDS, new ArrayBlockingQueue<>(5)); + for (int i = 0; i < 15; i++) { + MyTask task = new MyTask(i); + executor.execute(task); + System.out.println("线程池中线程数目: " + executor.getPoolSize() + " 队列中等待执行的任务数: " + + executor.getQueue().size() + " 已执行完的任务数: " + executor.getCompletedTaskCount()); + } + executor.shutdown(); + } +} + +public class MyTask implements Runnable { + + private int taskName; + public MyTask(int taskName) { + this.taskName = taskName; + } + + @Override + public void run() { + System.out.println("正在执行 Task: " + taskName); + try { + Thread.sleep(3000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println("Task: " + taskName + " 执行完毕"); + } +} +``` + +当线程池中的线程数大于五时,便会将后续任务添加到任务等待队列中,当任务等待队列也满了之后,便会创建新的线程。如果将上面 for 循环改为 20,则会抛 RejectedExecutionException 任务拒绝异常。 + +不过在 Java 中,并不会推荐直接使用 ThreadPoolExcutor,而是使用 Executors 提供的几种静态方法: + +```java + public static ExecutorService newFixedThreadPool(int nThreads) { + return new ThreadPoolExecutor(nThreads, nThreads, + 0L, TimeUnit.MILLISECONDS, + new LinkedBlockingQueue()); + public static ExecutorService newSingleThreadExecutor() { + return new FinalizableDelegatedExecutorService + (new ThreadPoolExecutor(1, 1, + 0L, TimeUnit.MILLISECONDS, + new LinkedBlockingQueue())); + } + public static ExecutorService newCachedThreadPool() { + return new ThreadPoolExecutor(0, Integer.MAX_VALUE, + 60L, TimeUnit.SECONDS, + new SynchronousQueue()); + } +``` #### 参考 diff --git a/images/Java/线程池.png b/images/Java/线程池.png new file mode 100644 index 0000000000000000000000000000000000000000..dd1f5e31ef9efe2f6016c3fe7d807380e156a0f4 GIT binary patch literal 30656 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 SE`z)wZHM9ZjPL(?^1lIE8x4;D literal 0 HcmV?d00001