大文件 and 多下载任务的封装(一)---线程池的封装(ThreadPool,TheadManager)

来源:互联网 发布:日系淘宝店铺推荐 编辑:程序博客网 时间:2024/05/01 19:13

ThreadManager

原文地址
大文件 and 多下载任务的封装二
大文件 and 多下载任务的封装三·

前段时间对三级缓存机制做了系统的分析,但是对于网络下载的问题还有很多,比如今天遇到的问题,针对一些需要下载大文件,并且需要进行多线程下载的应用来说,(比如,像一些应用商店,软件的下载和一些累似的多线程的下载类型)就需要用到线程池,下载就简单介绍对线程池的封装

一.为什么要使用线程池

根据android单线程模式规定,android只允许有一个主线程,也就是UI线程,一切更新UI的操作必须在UI线程中使用,然而对应的一切的耗时操作,只允许在子线称中执行,所以针对子线称的下载操作,可以使用线程池进行管理,所以封装线程吃对线程池管理工具,也是非常实用的。

  1. 提升性能。创建和消耗对象费时,费CPU资源.
  2. 防止内存过度消耗。控制活动线程的数量,防止并发线程过多。
  3. 最大的好处就是,当我们想使用时可以直接新建然后加入线程池即可,也可以对线程进行复用,当我们不想使用的时候直接就可以把它关闭。

二.为什么要对线程池进行封装

有的人可能会说, java.util.concurrent.ThreadPoolExecutor;提供了原生的线程池,我们为什么还要对它进行封装呢?直接使用不就好了,那么问题来了?

  1. .ThreadPoolExecutor的使用必须保证一个app中只能拥有一个(也就是必须保证单例模式),否则也无法保证子线程的数木
  2. 封装是为了更好的管理线程,是为了优化代码的使用效率,更好的管理代码。

三.线程池进行封装

####(一)原理分析

  1. 首先先看一下ThreadPoolExecutor的参数
/**    下面对线程池的方法参数进行解释,其余两个就不解说了,一些参数使用系统默认的即可,    Runtime.getRuntime().availableProcessors();进行设置    对于休息时间,则是为了考虑系统长时间运行而导致的系统发热现象,    一般情况下可以选择为0L**/ThreadPoolExecutor  executor = new ThreadPoolExecutor(                        //1.第一个参数:核心的线程数,                        corePoolSize,                        //2.第二个参数,默认使用的最大线程数                        maximumPoolSize,                        //3.线程执行时的休眠时间的数值,                        keepAliveTime,                          //4.线程执行时休眠的时间的单位,也就是上一个参数的单位                        TimeUnit.SECONDS,                        //5.线程的队列                        new LinkedBlockingQueue<Runnable>(),                         //6.生产线程的工厂                        Executors.defaultThreadFactory(),                       //7.线程异常的处理策略                        new ThreadPoolExecutor.AbortPolicy()        );
  1. 因为线程池必须保持一个app中只能有一个实例,所以我们使用单例模式,在这里可以使用懒汉模式
//这里使用的是ThreadManager类,把它设置称单例//而ThreadPool则是在内部类中引用  private static ThreadPool Instance;    //单例模式,获取线程池的实例    public  static ThreadPool getInstance(){        if(Instance == null){            synchronized (ThreadPool.class){                if(Instance == null){                    int threadCount = Runtime.getRuntime().availableProcessors();                    Instance = new ThreadPool(threadCount,threadCount,1L);                }            }        }        return Instance;    }
  1. 对与线程池来说,我们首先应该有一个向线程池中添加线程的操作
  public  void execute(Runnable r){  //当ThreadPoolExecutor为null时才新建一个,否则使用原有的。            if(executor == null){                executor = new ThreadPoolExecutor(                        corePoolSize,maximumPoolSize,keepAliveTime, TimeUnit.SECONDS,                        new LinkedBlockingQueue<Runnable>(), Executors.defaultThreadFactory(),                        new ThreadPoolExecutor.AbortPolicy());            }            if(executor != null){//如果不为空,那么就直接执行此子线称                executor.execute(r);            }        }
  1. 当我们对已经开始下载的线程突然不想下载了,或者点错了,那么就需要取消线程
//在这里我们只需要把线程从线程池中移除 public void cancel(Runnable r){            if(executor != null){            //虽然已经移除了,但是下载还是正在运行的,所以我们应该在子线称动态添加取消事件,进行取消                executor.getQueue().remove(r);            }        }
  1. 为了防止ThreadManager被直接new出对象,所以应该对构造方法进行限制
private Thread<Manager(){}

四.ThreadManager的使用

//这里是简单的使用Runnable r = new Runnable(){}ThreadManager.getInstance().execute(r);

五.代码

package com.example.orchid.googleplatstore.manager;import java.util.concurrent.Executors;import java.util.concurrent.LinkedBlockingQueue;import java.util.concurrent.ThreadPoolExecutor;import java.util.concurrent.TimeUnit;/** * Created by orchid * on 16-11-4. *  线程池类的封装 * */public class ThreadManager {    private static ThreadPool Instance;    //单例模式,获取线程池的实例    public  static ThreadPool getInstance(){        if(Instance == null){            synchronized (ThreadPool.class){                if(Instance == null){                    int threadCount = Runtime.getRuntime().availableProcessors();                    Instance = new ThreadPool(threadCount,threadCount,1L);                }            }        }        return Instance;    }    public static class ThreadPool{        private  ThreadPoolExecutor executor;        private  int corePoolSize;        private  int maximumPoolSize;        private  long keepAliveTime;        public ThreadPool(int corePoolSize,int maximumPoolSize,long keepAliveTime) {            this.corePoolSize = corePoolSize;            this.maximumPoolSize = maximumPoolSize;            this.keepAliveTime = keepAliveTime;        }        public  void execute(Runnable r){            if(executor == null){                //线程池执行者。                //参1:核心线程数;参2:最大线程数;参3:线程休眠时间;参4:时间单位;参5:线程队列;参6:生产线程的工厂;参7:线程异常处理策略                executor = new ThreadPoolExecutor(                        corePoolSize,maximumPoolSize,keepAliveTime, TimeUnit.SECONDS,                        new LinkedBlockingQueue<Runnable>(), Executors.defaultThreadFactory(),                        new ThreadPoolExecutor.AbortPolicy());            }            if(executor != null){                executor.execute(r);            }        }        //取消线程        public void cancel(Runnable r){            if(executor != null){                executor.getQueue().remove(r);            }        }    }}
1 0
原创粉丝点击