AsyncTask 第二篇线程篇

2016-04-03  本文已影响32人  王三的猫阿德

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

简介

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

线程之Thread&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类,可以帮助我们获取线程的执行结果。下面就详细的说明一下这两个接口和一个类。

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

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内部的实现了。

上一篇 下一篇

猜你喜欢

热点阅读