android子线程会自动销毁吗,Android 中的“子线程”解析

本文详细介绍了Android中子线程的使用,包括Thread与Runnable、Callable与Future的区别,线程池的实现及优势,IntentService与HandlerThread的工作原理,以及AsyncTask的使用和源码解析。探讨了子线程在处理耗时任务中的关键角色,以及如何通过不同方式管理线程生命周期,确保应用的高效和稳定运行。
摘要由CSDN通过智能技术生成

Android 中线程可分为主线程和子线程两类,其中主线程也就是UI线程,它的主要这作用就是运行四大组件、处理界面交互。子线程则主要是处理耗时任务,也是我们要重点分析的。

首先 Java 中的各种线程在 Android 里是通用的,Android 特有的线程形态也是基于 Java 的实现的,所以有必要先简单的了解下 Java 中的线程,本文主要包括以下内容:

Thread、Runnable

Callable、Future

线程池

IntentService、HandlerThread

AsyncTask

一、Thread、Runnable

在 Java 中要创建子线程可以直接继承Thread类,重写run()方法:

public class MyThread extends Thread {

@Override

public void run() {

}

}

// 启动线程

new MyThread().start();

或者实现Runnable接口,然后用Thread执行Runnable,这种方式比较常用:

public class MyRunnable implements Runnable {

@Override

public void run() {

}

}

// 启动线程

new Thread(new MyRunnable()).start();

简单的总结下:

Runnable 可以实现多个线程共享资源,可以参考网上卖票的例子

Runnable 可以避免 Java 中的单继承的限制

无法直接得到任务的执行结果

二、Callable、Future

Callable和Runnable类似,都可以用来处理具体的耗时任务逻辑的,但是但具体的差别在哪里呢?看一个小例子:

定义 MyCallable 实现了 Callable接口,和之前Runnable的run()方法对比下,call()方法是有返回值的哦,泛型就是返回值的类型:

public class MyCallable implements Callable {

@Override

public String call() throws Exception {

Log.e("call", "task start");

Thread.sleep(2000);

Log.e("call", "task finish");

return "hello thread";

}

}

一般会通过线程池来执行Callable(线程池相关内容后边会讲到),执行结果就是一个Future对象:

// 创建一个线程池

ExecutorService cachedThreadPool = Executors.newCachedThreadPool();

// 执行任务

Future result = cachedThreadPool.submit(new MyCallable());

try {

// 获取执行结果

Log.e("result", result.get());

} catch (InterruptedException e) {

e.printStackTrace();

} catch (ExecutionException e) {

e.printStackTrace();

}

可以看到,通过线程池执行 MyCallable 对象返回了一个 Future 对象,取出执行结果。

Future是一个接口,从其内部的方法可以看出它提供了取消任务(有坑!!!)、判断任务是否完成、获取任务结果的功能:

public interface Future {

boolean cancel(boolean mayInterruptIfRunning);

boolean isCancelled();

boolean isDone();

V get() throws InterruptedException, ExecutionException;

V get(long timeout, TimeUnit unit)

throws InterruptedException, ExecutionException, TimeoutException;

}

Future接口有一个FutureTask实现类,同时FutureTask也实现了Runnable接口,并提供了两个构造函数:

public FutureTask(Callable callable) {

}

public FutureTask(Runnable runnable, V result) {

}

用FutureTask一个参数的构造函数来改造下上边的例子:

ExecutorService cachedThreadPool = Executors.newCachedThreadPool();

FutureTask futureTask = new FutureTask<>(new MyCallable());

cachedThreadPool.submit(futureTask);

try {

Log.e("result", futureTask.get());

} catch (InterruptedException e) {

e.printStackTrace();

} catch (ExecutionException e) {

e.printStackTrace();

}

FutureTask内部有一个done()方法,代表Callable中的任务已经结束,可以用来获取执行结果:

FutureTask futureTask = new FutureTask(new MyCallable()){

@Override

protected void done() {

super.done();

try {

Log.e("result", get());

} catch (InterruptedException e) {

e.printStackTrace();

} catch (ExecutionException e) {

e.printStackTrace();

}

}

};

所以Future + Callable的组合可以更方便的获取子线程任务的执行结果,更好的控制任务的执行,主要的用法先说这么多了,其实AsyncTask内部也是类似的实现!

注意,Future并不能取消掉运行中的任务,这点在后边的AsyncTask解析中有提到。

三、线程池

Java 中线程池的具体的实现类是ThreadPoolExecutor,继承了Executor接口,这些线程池在 Android 中也是通用的。使用线程池的好处:

方便对线程进行管理

线程复用,避免大量创建、销毁线程带来的性能开销

可控制线程的最大并发数,避免线程之间抢占资源造成阻塞

常用的构造函数如下:

public ThreadPoolExecutor(

// 线程池的核心线程数,如果设置allowCoreThreadTimeOut属性为true,当闲置时间大于keepAliveTime会被终止掉,否则会一直存活不受keepAliveTime影响

int corePoolSize,

// 线程池能容纳的最大线程数,超过该数量的将会被阻塞

int maximum

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值