美文网首页
AsyncTask 第二篇线程篇

AsyncTask 第二篇线程篇

作者: 王三的猫阿德 | 来源:发表于2016-04-03 12:03 被阅读32次

转载注明出处:http://www.jianshu.com/p/c931df278244

简介

本篇主要针对AsyncTask中使用到的多线程知识进行讲解,也会涉及到一些基本的多线程知识。在上一篇中大家都知道了AsyncTask内部会起一个非UI线程去执行一些比较耗时的操作,那么这个线程在AsyncTask是怎么样被执行的,仅仅只是实例化一个Thread然后启动它吗?在内部对线程是怎么样处理的?这些都需要从AsyncTask的源代码中才能查看到,在看源代码之前先讲解一下关于AsyncTask内部涉及到的一些多线程知识,方便后面更快速的理解源代码,磨刀不误砍柴工!

线程之Thread&Runnable

说到多线程,通常很快就能想到Thread类和Runnable接口,相信大家并不陌生,直接说一下二者的区别吧。

  • 类和接口的区别,在java中只能单一的继承,但是可以实现多个接口,所以使用Runnable更灵活
  • 使用Runnable可以实现资源共享
  • Thread实现了Runnable接口

看起来好像Runnable非常好用,那么都用它不就行了吗?为什么要需要Thread呢?是因为Threadstart()方法是调用了本地的一个系统方法,来创建一个线程,这个才是实现多线程的根本,而run()方法只是线程中执行的具体任务,这也是在创建多线程时候,要调用start()方法而不是直接调用run()方法的原因。

使用起来也非常简单,看下面代码。因为Runnable仅仅是个接口,并没有start()方法,所以会依托于Thread。

//Thread使用
new Thread() {
    @Override
    public void run() {
        //具体操作
    }
}.start();

//Runnable使用
Runnable r = new Runnable() {
    @Override
    public void run() {
        //具体操作
    }
};
new Thread(r).start();

线程之Callable&Future&FutureTask

上面讲述了创建线程的两种方式,一种是继承Thread,另一种是实现Runnbale接口。这两种方式的问题在于,在执行完毕任务之后,无法获取执行的结果,也就是说,如果我们需要一个能够返回执行结果的线程,上面两种方式想要实现这种效果就需要通过共享资源或者使用线程间通信,这就比较麻烦了。

在java 1.5的时候,官方推出了Callable接口、Future接口、FutureTask类,可以帮助我们获取线程的执行结果。下面就详细的说明一下这两个接口和一个类。

  • Callable接口定义了一个可以返回结果的任务,但是可能会抛出异常,和Runnable接口有些类似,它们的实例可能被另一个线程执行,区别在于Callable能够返回执行结果,而且可能抛出异常。Runnable接口声明了一个run()方法,Callable接口声明了一个带返回结果的call()方法

    public interface Callable<V> {
        V call() throws Exception;
    }
    
  • Future接口表示异步操作执行完毕后返回的结果,该接口内部声明的方法用于检测异步操作是否完成、等待异步操作完成、获取异步操作结果。获取操作的执行结果只能通过get()方法,如果操作已经执行完毕,就直接返回结果,如果操作还在执行,就会一直阻塞,等待操作执行完毕。Future接口内部声明了五个方法,都很好理解。

    public interface Future<V> {
        boolean cancel(boolean mayInterruptIfRunning);
        boolean isCancelled();
        boolean isDone();
        V get();
        V get(long timeout, TimeUnit unit);
    }
    
  • FutureTask类实现了RunnableFuture<V>接口,而RunnableFuture<V>继承了RunnableFuture<V>接口,也就是说FutureTask既可以当做一个线程具体的执行任务也可以当做一个线程具体任务的执行结果。它是一个具体的实现类,具体代码就不贴了。

我们来看一下具体的使用吧。

try {
    ExecutorService executorService = Executors.newCachedThreadPool();
    Future<String> future = executorService.submit(new Callable<String>() {
        @Override
        public String call() throws Exception {
            return "result";
        }
    });
    String result = future.get();
} catch (InterruptedException e) {
    e.printStackTrace();
} catch (ExecutionException e) {
    e.printStackTrace();
}

实例化了一个ExecutorService类,并且传入了一个匿名Callable类,然后定义了一个Future指向了任务执行完毕后返回的结果,最后调用Future.get()方法获取返回结果。

前面说了,FutureTask实现了Runnable接口和Future接口,它既可以作为一个线程内部具体的执行任务,又可以座位线程内部具体任务执行完毕后返回的结果。所以还可以这样用。

try {
    Executor executor = Executors.newCachedThreadPool();
    FutureTask<String> futureTask = new FutureTask<String>(new Callable<String>() {
        @Override
        public String call() throws Exception {
            return "result";
        }
    });
    executor.execute(futureTask);
    String result = futureTask.get();
} catch (InterruptedException e) {
    e.printStackTrace();
} catch (ExecutionException e) {
    e.printStackTrace();
}

首先实例化了一个Executor,然后实例化了一个FutureTask类,并将一个匿名的Callable类传入,然后将FutureTask当做是RunnableExecutor去执行,最后调用FutureTask.get()方法获取执行结果。

总结

通过上面的介绍,在不使用内存共享或者线程间通信技术前提下,我们可以直接获取线程执行完毕后返回的结果,大大的降低了研发的成本。

一般是通过Calllable+Future或者Callable+FutureTask来实现这种效果,当然还有更多的使用方法,同时在FutureFutureTask使用过程也有很多细节问题,但是这篇文章主要是为了理解AsyncTask源代码实现而进行的磨刀的讲解,所以并不深入,而下一篇就是真正的砍柴了,也终于可以初窥AsyncTask内部的实现了。

相关文章

  • AsyncTask 第二篇线程篇

    转载注明出处:http://www.jianshu.com/p/c931df278244 简介 本篇主要针对Asy...

  • 源码分析AsyncTask的工作原理

    一、AsyncTask原理介绍 AsyncTask的实现原理 = 线程池+ Handler 其中:线程池用于线程调...

  • 第11章 Android的线程和线程池

    1.主线程和子线程 11.2Android中的线程形态 11.2.1 AsyncTask AsyncTask 是一...

  • Android面试之线程和线程池

    Android中的线程形态 AsyncTask底层用到了线程池。AsyncTask封装了线程池和Handler,它...

  • Asynctask

    底层:handler + 线程池 Asynctask 的实例必须在主线程中创建 Asynctask 的execut...

  • async task 注意地方

    AsyncTask用的是线程池,线程不用就会放回池中. 有新的AsyncTask会取出已有线程,之后开始执行,这就...

  • AsyncTask原理及不足

    AsyncTask理解: AsyncTask是Handler与线程池的封装。 网络请求等耗时操作在线程池中完成,通...

  • AsyncTask原理分析

    AsyncTask在安卓中常用于线程间通信。在子线程执行耗时任务,在主线程更新UI。 AsyncTask内部封装了...

  • AsyncTask指南

    AsyncTask指南 通过AsyncTask,可以正确,轻松地使用UI线程。此类允许您执行后台操作并在UI线程上...

  • Android进阶-线程池

    在上一篇文章(为什么要学习) AsyncTask 原理 提到了线程池,那么现在来学习学习 Android 的线程池...

网友评论

      本文标题:AsyncTask 第二篇线程篇

      本文链接:https://www.haomeiwen.com/subject/hwlulttx.html