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<Runnable>(), 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<ThreadWorker>();
            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),里面都有用到线程池,而且用的很深,看不懂。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android 线程池主要有以下四种类型: 1. FixedThreadPool:该线程池线程数量是固定的,如果线程处于空闲状态,它们将会被保留在池,当任务到达时,它们会被立即执行。如果线程池的所有线程都处于忙碌状态,任务将会被放入到队列等待执行。 2. CachedThreadPool:该线程池线程数量是不固定的,线程数会根据任务的多少自动调整。如果有大量任务需要执行,会创建更多的线程来处理这些任务,如果有较少的任务需要执行,线程池线程数量会自动减少。 3. SingleThreadExecutor:该线程池只有一个线程,所有任务将会在这个线按顺序执行。如果该线程因为异常而终止,那么将会创建一个新的线程来代替它。 4. ScheduledThreadPool:该线程池用于执行一些需要定时执行的任务,比如定时执行一些操作、周期性地执行某些任务等。 以下是一个使用 FixedThreadPool 的示例代码: ``` ExecutorService executorService = Executors.newFixedThreadPool(5); // 提交任务给线程池执行 executorService.submit(new Runnable() { @Override public void run() { // 执行任务的代码 } }); // 关闭线程池 executorService.shutdown(); ``` 其他类型的线程池使用方式与 FixedThreadPool 类似,只需要将 `Executors.newFixedThreadPool()` 替换为对应的方法即可。在使用线程池时,需要根据具体的业务需求选择合适的线程池类型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值