线程池

线程池的作用:

一、线程池作用就是限制系统中执行线程的数量。
根据系统的环境情况,可以自动或手动设置线程数量,达到运行的最佳效果;少了浪费了系统资源,多了造成系统拥挤效率不高。用线程池控制线程数量,其他线程排队等候。一个任务执行完毕,再从队列的中取最前面的任务开始执行。若队列中没有等待进程,线程池的这一资源处于等待。当一个新任务需要运行时,如果线程池中有等待的工作线程,就可以开始运行了;否则进入等待队列。
二、采用线程池的优势?

  1. 避免线程频繁创建消毁。
    虽然采用Thread 创建线程可以实现耗时操作,但线程的大量创建和销毁,会造成过大的性能开销。
    2.避免系统资源紧张。
    当大量的线程一起运作的时候,可能会造成资源紧张,上面也介绍过线程底层的机制就是切分CPU的时间,而大量的线程同时存在时可能造成互相抢占资源的现象发生,从而导致阻塞的现象。
    3.更好地管理线程。
    以下载功能为例,一般情况下,会有限制最大并发下载数目,而利用线程池我们可以灵活根据实际需求来设置同时下载的最大量、串行执行下载任务顺序、实现队列等待等功能。
    三、Android 中常用的几种线程池。
    3.1 FixedThreadPool
    它的源码如下:
public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

从源码我们可以看出两个特征:

1.它只有一个传入参数,即固定核心线程数

它只提供了一个nThreads,供外部传入进来,并且它的核心线程数和最大线程数是一样的。这说明在FixedThreadPool中没有非核心线程,所有的线程都是核心线程。

  1. 线程的超时时间为0。

这说明核心线程即使在没有任务可执行的时候,也不会被销毁,这样可让FixedThreadPool更快速的响应请求。最后的线程队列是一个LinkedBlockingQueue,但是LinkedBlockingQueue却没有参数,这说明线程队列的大小为Integer.MAX_VALUE(2^31 - 1)

从以上源码参数我们对FixedThreadPool的工作特点应该也有大体的理解了,接下来我们继续分析其他几个线程池。

3.2 SingleThreadExecutor
它的源码如下:

public static ExecutorService newSingleThreadExecutor() {  
    return new FinalizableDelegatedExecutorService  
        (new ThreadPoolExecutor(1, 1,  
                                0L, TimeUnit.MILLISECONDS,  
                                new LinkedBlockingQueue<Runnable>()));  

从源码我们可以很容易发现 SingleThreadExecutor和FixedThreadPool很像,不同的是SingleThreadExecutor的核心线程数只有1, 也就是只能同时有一个线程被执行。使用它可以避免我们处理线程同步问题。
打个比喻,它就类似于排队买票,一次只能同时处理一个人的事务。其实如果我们把FixedThreadPool的参数传为1,就和SingleThreadExecutor的作用一致了。
3.3 CachedThreadPool
它的源码如下:

public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

从源码可以看到,CachedThreadPool中是没有核心线程的,但是它的最大线程数却为Integer.MAX_VALUE,另外,CachedThreadPool是有线程超时机制的,它的超时时间为60秒。

由于最大线程数为无限大,所以每当添加一个新任务进来的时候,如果线程池中有空闲的线程,则由该空闲的线程执行新任务;如果没有空闲线程,则创建新线程来执行任务。

根据CachedThreadPool的特点,在有大量耗时短的任务请求时,可使用CachedThreadPool,因为当CachedThreadPool中没有新任务的时候,它里边所有的线程都会因为60秒超时而被终止。
3.4 ScheduledThreadPool
它的源码如下:

public ScheduledThreadPoolExecutor(int corePoolSize) {  
    super(corePoolSize, Integer.MAX_VALUE,  
          DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,  
          new DelayedWorkQueue());  
} 

从源码可以看出,它的核心线程数量是固定的,但是非核心线程无穷大。当非核心线程闲置时,则会被立即回收。
ScheduledThreadPool也是四个当中唯一一个具有定时定期执行任务功能的线程池。它适合执行一些周期性任务或者延时任务。

延时启动任务示例:

ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(2);
            Runnable runnable = new Runnable(){
                @Override
                public void run() {
                    //TODO method();
                }
            };
        
        //延迟一秒执行
        scheduledExecutorService.schedule(runnable, 1, TimeUnit.SECONDS);


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值