Android中的线程池及使用

Android中的线程池及使用

线程池能处理业务中多个线程并发的问题,避免大量产生新的线程相互抢占系统资源,可以统一通过线程池来配置不同参数来管理线程。java中已经内置好了四种线程池供我们使用。


  • 线程池创建的参数
    corePoolSize 核心线程数 一般情况下一直存活,即使没有任务

  • maximumPoolSize 最大线程池数量

    keepAliveTime 非核心线程的闲置时长 当非核心线程的空闲时间超过该时长,会被回收节省资源,当设置allowCoreThreadTimeOut为true时候,核心线程也会被该规则回收

    TimeUnit 指定keepAliveTime的时间单位

    BlockingQueue 线程池的任务队列 通过execute(Runnable command)方法将任务放入队列中

    ThreadFactory 线程工厂 是一个接口 Thread newThread(Runnable var1)用来创建新的线程

    RejectedExecutionHandler 线程池对拒绝任务的处理策略 当线程池满了或者产生其他异常,对未进入线程池的任务进行大的处理策略,可以不用传,有默认值。


JAVA中已经为我们提供了四种参数设置好的线程池

  • 定长线程池 FixedThreadPool
  //nThreads  核心线程数
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4);
        //执行任务
        fixedThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                Log.e("tag","执行任务");
            }
        });
        //关闭线程池
        fixedThreadPool.shutdown();

特点:指定一个一定数量的工作线程的线程池,可以节省线程创建的时间提高使用效率,当工作线程达到最大线程数数量,新的任务会进入等待队列。但是当线程池空闲时候,空闲线程也不会销毁,因为创建的只为核心线程。

  • 定时线程池 ScheduledThreadPScheduledExecutorService
 ScheduledExecutorService scheduledExecutorService =
                Executors.newScheduledThreadPool(5);
        scheduledExecutorService.schedule(new Runnable() {
            @Override
            public void run() {
                Log.e("tag", "延迟2秒再提交任务");
            }
        }, 2, TimeUnit.SECONDS);
        scheduledExecutorService.scheduleWithFixedDelay(new Runnable() {
            @Override
            public void run() {
                Log.e("tag", "延迟2秒后,每隔1秒执行任务");
            }
        }, 2, 1, TimeUnit.SECONDS);
        scheduledExecutorService.shutdown();

特点:指定一个指定数量的核心线程数,非核心线程数无限制。支持定时延迟执行任务和周期性执行任务。没超过核心线程数情况可减少线程创建时间,超过会新建工作线程,闲置时候会被马上回收。

  • 可缓存线程池 CachedThreadPool
ExecutorService executorService = Executors.newCachedThreadPool();
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                Log.e("执行任务","执行任务");
            }
        });
        executorService.shutdown();

特点:没有核心线程数,非核心线程可无限扩大,使用灵活,空闲线程也会被即时回收。任何线程任务提交是,会被立即执行,无需等待。

  • 单线程化线程池 SingleThreadExecutor
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
        singleThreadExecutor.execute(new Runnable() {
            @Override
            public void run() {
                Log.e("tag","执行任务");
            }
        });
        singleThreadExecutor.shutdown();

特点:只创建一个唯一的核心线程来工作,所有任务按照(先进先出,后进先出)的规则执行。可解决银行存钱取钱模型问题,同时保证线程安全,数据不会错乱。


几个大库使用的线程池:

  • okhttp使用线程池,代码如下:

创建非核心线程为无限大,实际上受maxRequests(默认值为65)影响。

 public synchronized ExecutorService executorService() {
    if (executorService == null) {
      executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,
          new SynchronousQueue(), Util.threadFactory("OkHttp Dispatcher", false));
    }
    return executorService;
  }
synchronized void enqueue(AsyncCall call) {
    if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
      runningAsyncCalls.add(call);
      executorService().execute(call);
    } else {
      readyAsyncCalls.add(call);
    }
  }
  • rxjava中的线程池的使用
    io工作线程,创建定长线程。
CachedWorkerPool(long keepAliveTime, TimeUnit unit, ThreadFactory threadFactory) {
            this.keepAliveTime = unit != null ? unit.toNanos(keepAliveTime) : 0L;
            this.expiringWorkerQueue = new ConcurrentLinkedQueue();
            this.allWorkers = new CompositeDisposable();
            this.threadFactory = threadFactory;

            ScheduledExecutorService evictor = null;
            Future task = null;
            if (unit != null) {
                evictor = Executors.newScheduledThreadPool(1, EVICTOR_THREAD_FACTORY);
                task = evictor.scheduleWithFixedDelay(this, this.keepAliveTime, this.keepAliveTime, TimeUnit.NANOSECONDS);
            }
            evictorService = evictor;
            evictorTask = task;
        }

自己简单的封装

public class ThreadPoolManager {

    private long keepAliveTime = 10;//存活时间
    private TimeUnit unit = TimeUnit.MINUTES;
    private final ThreadPoolExecutor mThreadPoolExecutor;

    //静态内部类,
    private static class HelperSinger{
        private static ThreadPoolManager sSingletonTest = new ThreadPoolManager();
    }

    private ThreadPoolManager(){
        int corePoolSize = Runtime.getRuntime().availableProcessors()*2+1;
        int maxmunPoolSize = corePoolSize;
        //LinkedBlockingQueue  先进先去
        //defaultThreadFactory  线程工厂
        //AbortPolicy  队列满额的拒绝策略
        mThreadPoolExecutor = new ThreadPoolExecutor(corePoolSize, maxmunPoolSize,
                keepAliveTime, unit, new LinkedBlockingQueue<>(),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());

    }

    public static ThreadPoolManager getInstace(){
        return HelperSinger.sSingletonTest;
    }

    public void execute(Runnable runnable){
        if(runnable==null)return;

        mThreadPoolExecutor.execute(runnable);
    }
    /**
     * 从线程池中移除任务
     */
    public void remove(Runnable runnable){
        if(runnable==null)return;
        mThreadPoolExecutor.remove(runnable);
    }


    public void shutDown(Runnable runnable){
        if(mThreadPoolExecutor.isShutdown())return;
        mThreadPoolExecutor.shutdown();
    }
}

总结:多看其他库的源码(okhttp,rxjava,fresco),里面都有用到线程池,而且用的很深,看不懂。

你可能感兴趣的:(android基础)