一、线程
在Android开发中,由于需要进行联网、下载数据、保存数据等操作,开发者无法完全在主线程中进行开发。因此,线程成为了必不可少的工具。在Android 4.0之前的手机版本中,开发者可以在主线程中请求网络,但这已经相对较为陈旧。
在Android中,可以随意创建线程,但这也容易导致线程不可控、内存泄漏、创建线程消耗资源等问题。为了解决这些问题,我们需要对线程进行控制。
二、线程池
线程池的概念是:一个用于存放线程的大池子。在Android开发中,我们可以使用不同的线程池来满足不同的需求。以下是一些常见的系统线程池:
1. FixedThreadPool:创建定长线程的线程池。
2. CachedThreadPool:需要时创建新线程,超时后销毁线程。
3. SingleThreadPool:单个线程的线程池。
4. ScheduledThreadPool:可以定时执行任务的线程池。
这些线程池的原理与我们接下来要讲的内容密切相关。接下来,我们将介绍如何自定义线程池以及一些必须了解的参数:
1. corePoolSize:核心线程池大小,即线程池中主要工作的线程数量。
2. maximumPoolSize:线程池最大线程数。
3. keepAliveTime:空闲线程可保持的时间,如果启用了allowCoreThreadTimeOut方法,空闲线程会在这段时间后自动销毁;如果没有启用,只要不超过corePoolSize,空闲线程也不会销毁。
4. Unit:keepAliveTime的时间单位。
5. workQueue:阻塞队列,当任务达到corePoolSize时,会被放入这个队列。
常见的几种BlockingQueue实现如下:
1. ArrayBlockingQueue:有界的数组队列。
2. LinkedBlockingQueue:可支持有界/无界的队列,使用链表实现。
3. PriorityBlockingQueue:优先队列,可以针对任务排序。
4. SynchronousQueue:队列长度为1的队列,与Array的区别在于:客户端线程提交到block queue会是一个阻塞过程,直到有一个worker thread连接上来poll task。
在Android开发中,我们经常需要处理并发编程的问题,其中线程与线程池是关键部分。在这篇文章中,我们将详细介绍线程工厂和拒绝处理策略。
线程工厂主要用来创建线程。在Java中,线程工厂接口ThreadFactory的唯一方法是newThread(Runnable r),它返回一个新创建的线程。这个方法通常由开发者实现,以便根据自己的需求定制线程的创建方式。
拒绝处理策略表示当任务被拒绝时的处理方法。当参数maximumPoolSize达到后,如果任务无法执行,会采取以下四种策略之一:
1. ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
2. ThreadPoolExecutor.DiscardPolicy:丢弃任务,但不抛出异常。
3. ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列中最早的任务,然后重新尝试执行任务(重复此过程)。
4. ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务。
用户还可以自定义拒绝处理策略,实现RejectedExecutionHandler接口。这样可以根据自己的需求来选择合适的策略。
下面是一个简单的代码示例:
```java
import java.util.concurrent.*;
public class ThreadPoolExample {
public static void main(String[] args) {
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(2, 4, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>(10));
threadPool.allowCoreThreadTimeOut(true);
RejectedExecutionHandler handler = new MyRejectedExecutionHandler();
threadPool.setRejectedExecutionHandler(handler);
}
}
```
在这个示例中,我们创建了一个具有两个核心线程、四个最大线程、60秒的空闲线程存活时间以及10个任务等待队列的线程池。当任务被拒绝时,我们使用自定义的拒绝处理策略MyRejectedExecutionHandler。