美文网首页
Android-线程池

Android-线程池

作者: 有腹肌的豌豆Z | 来源:发表于2020-09-22 10:17 被阅读0次
    • 线程池就是创建若干个可执行的线程放入一个池(容器)中,有任务需要处理时,会提交到线程池中的任务队列,处理完之后线程并不会立即被销毁,而是仍然在线程池中等待下一个任务。

    为什么要使用线程池

    • 减少线程频繁创建、销毁的开销;
    • 好控制并发量,降低OOM的可能,至于原因文中会说;
    • 提高程序的响应速度,因为可以省去部分创建的过程;

    图解

    Executor接口

    public interface Executor {
        /**
         * 就一个方法,用来执行线程任务的,类似于Thread的start()方法
         */
        void execute(Runnable command);
    }
    
    
    • 由于Executor是一个接口,所以execute是由具体的实现类来完成的,调用这个方法,可能会出现如下情况:
      1.创建一个新线程并立即启动;
      2.复用线程池中空闲的线程来执行任务;
      3.进入一个阻塞队列中排队;
      4.抛出异常/拒绝接收该任务,这个要看具体的拒绝策略,默认抛出异常。

    ExecutorService接口

    • 继承自Executor接口,我们常用的很多方法就是在这个接口中定义的。主要涉及到:提交任务、关闭线程、获取结果。
    
    public interface ExecutorService extends Executor {
    
        /**
         * 关闭线程池,新提交的任务会被拒绝,但是已经提交的任务会继续执行
         */
        void shutdown();
    
        /**
         * 关闭线程池,新提交的任务会被拒绝,并且尝试关闭正在执行的任务
         */
        List<Runnable> shutdownNow();
    
        /**
         * 线程池是否已关闭
        */
        boolean isShutdown();
    
        /**
         * 如果调用了shutdown或者shutdownNow之后,所有的任务都结束了,那么返回true,否则返回false
         */
        boolean isTerminated();
    
        /**
         * 当调用shutdown 或 shutdownNow之后,再调用这个方法,会
         *等待所有的任务执行完成,直到超时(超过timeout)或者说当前的线程被中断了
         */
        boolean awaitTermination(long timeout, TimeUnit unit)
            throws InterruptedException;
    
    
        /**
         * 提交一个Runnable 任务
         */
        Future<?> submit(Runnable task);
    
        /**
         * 执行所有任务,返回 Future 类型的一个 list
         */
        <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
            throws InterruptedException;
    }
    
    

    AbstractExecutorService

    • 抽象类,实现了ExecutorService接口。主要封装了通过submit方式提交任务的一些操作。
    • 注意: 不需要获取结果,可以用 execute 方法;需要获取结果(FutureTask)用 submit 方法。

    Executors

    • 这是大多数人最常用的一个类,实质上就是一个工具类。可以快速的构建一个线程池对象,常见的操作有如下:
       /**
         * 创建一个固定大小的线程池,而且全是核心线程,
         * 会一直存活,除非特别设置了核心线程的超时时间
         */
        public static ExecutorService newFixedThreadPool(int nThreads) {
            return new ThreadPoolExecutor(nThreads, nThreads,
                                          0L, TimeUnit.MILLISECONDS,
                                          new LinkedBlockingQueue<Runnable>());
        }
    
       /**
         * 创建了一个没有大小限制的线程池,全是非核心线程;如果线程
         * 空闲的时间超过60s就会被移除
         */
        public static ExecutorService newCachedThreadPool() {
            return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                          60L, TimeUnit.SECONDS,
                                          new SynchronousQueue<Runnable>());
        }
    
       /**
         * 这个线程池只有1个唯一的核心线程
         */
        public static ExecutorService newSingleThreadExecutor() {
            return new FinalizableDelegatedExecutorService
                (new ThreadPoolExecutor(1, 1,
                                        0L, TimeUnit.MILLISECONDS,
                                        new LinkedBlockingQueue<Runnable>()));
        }
    
       /**
         * 创建一个定长的线程池,可以执行周期性的任务
         */
        public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
            return new ScheduledThreadPoolExecutor(corePoolSize);
        }
    
    
    • 可以看出这几种方式最后都是通过ThreadPoolExecutor来实现的,所以下面就来研究一下今天的主角ThreadPoolExecutor,等理解了这个类,也就可以掌握线程池等工作原理,甚至可以根据自己的策略来自定义线程池。

    相关文章

      网友评论

          本文标题:Android-线程池

          本文链接:https://www.haomeiwen.com/subject/amrusktx.html