美文网首页Android
Android线程管理 - ExecutorService线程池

Android线程管理 - ExecutorService线程池

作者: 世道无情 | 来源:发表于2018-05-14 10:39 被阅读0次

    1. 为什么要引入线程池?


    • 如果有100个下载任务,每次 new Thread(),很耗性能;
    • new多个线程也缺乏管理,线程过多之间会相互竞争,占用资源多,导致系统瘫痪;

    所以就引入线程池;

    2. 线程池好处?


    • 解决了线程反复的创建和销毁,做到线程可以反复使用;

    3. ExecutorService介绍?


    • ExecutorService是线程池,是一个接口,继承自Executor接口;

    4. Executors工厂类


    Executors工厂类提供四种线程池:newSingleThreadExecutor、newScheduledThreadPool、newCacheThreadPool、newFixedThreadPool;

    1>:newSingleThreadExecutor用法

    • 创建一个单线程的线程池,它只用这一个线程来完成20个任务,保证所有任务按照指定顺序执行;

    代码如下:

        /**
         * 单线程的线程池:
         *          只会用一个线程来执行任务,保证所有任务按照指定顺序执行
         */
        private void newSingleThreadExecutor() {
            ExecutorService singleThreadPool = Executors.newSingleThreadExecutor();
            for (int i = 1; i <= number; i++) {
                final int index = i;
                singleThreadPool.execute(new Runnable() {
                    @SuppressLint("LongLogTag")
                    @Override
                    public void run() {
                        String threadName = Thread.currentThread().getName();
                        Log.e("TAG", "线程:"+threadName+",正在执行第" + index + "个任务");
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                });
            }
        }
    
    • 运行结果如下:


      图片.png
    • 可以看到:
      总共只创建一个线程,第一个执行完之后再去执行第二个,第二个执行完再去执行第三个...;

    2>:newScheduledThreadPool用法

    • 创建一个定长线程,可以执行定时的、周期性的任务;

    代码如下:

        /**
         *  每次创建一个定长的线程:
         *              可执行定时的、周期性的任务
         */
        private void newScheduledThreadPool() {
            ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
            //延迟2秒后执行该任务
            scheduledThreadPool.schedule(new Runnable() {
                @SuppressLint("LongLogTag")
                @Override
                public void run() {
                    String threadName = Thread.currentThread().getName();
                    Log.e("TAG", "线程:" + threadName + ",正在执行");
                }
            }, 2, TimeUnit.SECONDS);
            //延迟1秒后,每隔2秒执行一次该任务
            scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
                @Override
                public void run() {
                    String threadName = Thread.currentThread().getName();
                    Log.e("TAG", "线程:" + threadName + ",正在执行");
                }
            }, 1, 2, TimeUnit.SECONDS);
        }
    
    • 运行结果如下:


      图片.png
    • 可以看到:
      每次只是创建一个线程,每隔2秒执行一次;

    3>:newCacheThreadPool:

    创建一个可缓存的线程池,如果线程池长度超过处理需要,可以回收空闲的线程;

    代码如下:

        /**
         * 可缓存的线程池:
         *          如果线程池超过处理需要,可回收空闲线程
         */
        private void newCachedThreadPool() {
            ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
            for (int i = 1; i <= number; i++) {
                final int index = i;
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                cachedThreadPool.execute(new Runnable() {
                    @Override
                    public void run() {
                        String threadName = Thread.currentThread().getName();
                        Log.e("TAG", "线程:" + threadName + ",正在执行第" + index + "个任务");
                        try {
                            long time = index * 500;
                            Thread.sleep(time);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                });
            }
        }
    
    • 运行结果如下:


      图片.png
    • 可以看到:
      a:缓存线程池大小不固定,可以创建多个线程;
      b:在使用缓存线程池时候,先查看线程池中是否有以前创建的线程,如果有,就复用;如果没有,就创建线程,然后添加到线程池中;
      c:缓存的线程池通常用于执行生存期比较短的异步任务;

    4>:newFixedThreadPool用法

    • 创建一个可重用的、固定的线程数的线程池;

    代码如下:

        /**
         * 可重用的、固定的线程数的线程池
         *              固定的线程数是5
         */
        private void newFixedThreadPool() {
            ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);
            for (int i = 1; i <= number; i++) {
                final int index = i;
                fixedThreadPool.execute(new Runnable() {
                    @Override
                    public void run() {
                        String threadName = Thread.currentThread().getName();
                        Log.e("TAG", "线程:"+threadName+",正在执行第" + index + "个任务");
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                });
            }
        }
    
    • 运行结果如下:


      图片.png
    • 可以看到:
      a:只会创建5个线程来执行任务,其余的任务都添加在 缓存队列中,当线程池中的线程执行完之后,再从 缓存队列中取任务继续执行;

    相关文章

      网友评论

        本文标题:Android线程管理 - ExecutorService线程池

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