• android-线程池-最顺手的写法


    引子

    关于线程池,在这里写出几种最顺手的写法,至于原理以及各种细节。放后面再填;

    经过查证,凡是 以前new Thread()的地方,貌似都可以用线程池来执行,优化内存消耗。

    代码

    系统提供的4种预设线程池类:

     1      Runnable runnable = new Runnable() {
     2             @Override
     3             public void run() {
     4                 Log.d("atm", "假装有执行过程·");
     5             }
     6         };
     7 
     8         //第一类
     9         // 全部由核心线程去实现,并不会被回收,没有超时限制和任务队列的限制,会创建一个定长线程池,
    10         // 可控制线程最大并发数,超出的线程会在队列中等待
    11         ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4);
    12         fixedThreadPool.execute(runnable);
    13 
    14         //第二类
    15         //该模式下线程数量不定的线程池,只有非核心线程,最大值为Integer.MAX_VALUE,会创建一个可缓存线程池,
    16         // 如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程
    17         ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
    18         cachedThreadPool.execute(runnable);
    19 
    20         //第三类
    21         //该模式下核心线程是固定的,非核心线程没有限制,非核心线程闲置时会被回收。
    22         // 会创建一个定长线程池,执行定时任务和固定周期的任务
    23         ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(4);
    24         scheduledThreadPool.schedule(runnable, 2000, TimeUnit.SECONDS);//2000ms后执行。
    25         scheduledThreadPool.scheduleAtFixedRate(runnable, 10, 1000, TimeUnit.MILLISECONDS);//延迟10ms后,每隔1000ms执行一次
    26 
    27         //第四类,
    28         //该模式下线程池内部只有一个线程,所有的任务都在一个线程中执行,会创建一个单线程化的线程池,
    29         // 它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行
    30         ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
    31         singleThreadExecutor.execute(runnable);

    不用系统的,而是自己定义各种参数:

     1 import android.support.annotation.NonNull;
     2 
     3 import java.util.concurrent.Callable;
     4 import java.util.concurrent.Future;
     5 import java.util.concurrent.LinkedBlockingDeque;
     6 import java.util.concurrent.ThreadFactory;
     7 import java.util.concurrent.ThreadPoolExecutor;
     8 import java.util.concurrent.TimeUnit;
     9 import java.util.concurrent.atomic.AtomicInteger;
    10 
    11 /**
    12  */
    13 public class CustomThreadPool {
    14 
    15     private static final int CORE_POOL_SIZE = 3;//核心线程数目
    16     private static final int MAX_POOL_SIZE = 20;//最大线程数,除了核心线程就是非核心线程
    17     private static final int ALIVE_TIME = 5;//非核心线程允许闲置的最大时长
    18 
    19     private static final CustomThreadPool instance;
    20 
    21     private final ThreadPoolExecutor pool;
    22 
    23     static {
    24         instance = new CustomThreadPool();
    25     }
    26 
    27     private CustomThreadPool() {
    28         //参数逐个解析
    29         /**
    30          * @param 核心线程的数目,即使他们是闲置状态,也不会被回收,除非你设置 allowCoreThreadTimeOut,让核心线程也有超时时间(不过一般不这么做)
    31          * @param 线程池的最大容量,可以容纳核心线程和非核心线程
    32          * @param 当线程数目大于核心线程数,这个值是被回收的最大闲置时间,超出则会被回收
    33          * @param 超时时间的单位(一般用秒,或者毫秒)
    34          * @param 等待队列,当核心线程都在工作,而又有新的任务需要执行,这些任务则会先进入等待队列(但是如果进不去,或者队列满了,就会尝试用非核心线程)
    35          * @param 生成线程的工厂(一般都会自己new 一个类继承ThreadFactory)
    36          * @throws IllegalArgumentException 参数异常
    37          *         可能抛出的异常,
    38          *         比如,你把核心线程数设置为负数;
    39          *         或者超时时间设置为负数
    40          *         或者最大线程数是非正数;
    41          *         或者最大线程数小于 核心线程数
    42          * @throws NullPointerException
    43          *         当 工作队列是空,或者 线程工厂,对象是空,就会报空指针
    44          */
    45         pool = new ThreadPoolExecutor(CORE_POOL_SIZE, MAX_POOL_SIZE, ALIVE_TIME, TimeUnit.SECONDS, new LinkedBlockingDeque<Runnable>(), new MyThreadFactory());
    46     }
    47 
    48     public static CustomThreadPool getInstance() {
    49         return instance;
    50     }
    51 
    52     /**
    53      * 执行,无返回值
    54      *
    55      * @param r
    56      */
    57     public void execute(Runnable r) {
    58         pool.execute(r);
    59     }
    60 
    61     /**
    62      * 提交,有返回值
    63      *
    64      * @param r
    65      * @return
    66      */
    67     public Future<String> submit(Runnable r, String s) {
    68         return pool.submit(r, s);
    69     }
    70 
    71     public Future<String> submit(Callable<String> callable) {
    72         return pool.submit(callable);
    73     }
    74 
    75     private class MyThreadFactory implements ThreadFactory {
    76 
    77         private final AtomicInteger mCount = new AtomicInteger(1);
    78 
    79         @Override
    80         public Thread newThread(@NonNull Runnable r) {
    81             Thread thread = new Thread(r, "GWThreadPool-" + mCount.getAndIncrement());
    82             thread.setPriority(Thread.NORM_PRIORITY - 1);
    83             thread.setDaemon(false);
    84             return thread;
    85         }
    86     }
    87 
    88 }

    带返回值的执行,以及不带返回值的执行;

     1  private void test2() {
     2         //如果你想执行一个带返回值的任务,任务执行完成之后,返回结果,用下面的代码
     3         try {
     4             Callable<String> callable = new Callable<String>() {// 注意这里不是Runnable,而是Callable,
     5                 @Override
     6                 public String call() {
     7                     return "哈哈哈";
     8                 }
     9             };
    10 
    11             //````如果你想执行任务,并且要取执行完成之后的返回值,用submit吧
    12             Future<String> s = CustomThreadPool.getInstance().submit(callable);//执行,submit 有返回值
    13             //下面有5个API可供调用
    14             /**
    15              *  尝试取消任务的执行。这种尝试将会失败,当任务已经完成,已经被取消,或者因为某种原因不能被取消。
    16              *  如果成功取消,这个任务还没开始的话,那这个任务将永远不会执行,
    17              *  如果任务已经开始,那就要 mayInterruptIfRunning 参数值将会决定是否要尝试去终止任务;(true,尝试终止,false,不去尝试;至于为什么这里是尝试,而不是一定终止,参照本段开头;)
    18              *  当这个方法返回,后来的调用isDone将会永远返回true,也就是说,取消也算做是完成?
    19              *  后来的调用isCanceled   将会永远返回true,如果这个方法返回true的话。
    20              * @param mayInterruptIfRunning  是否执行这个任务线程的线程能够被中断;true能够中断,false,将会继续执行直到完成;
    21              * @return 返回值,false,如果这个任务不能被取消,典型的就是这个任务已经完成了·· 其他情况,返回true;
    22              */
    23             s.cancel(true);// 取消任务,参数的意思是:是否允许在执行过程中中断; 如果true,不管是不是已经开始任务,都让他终止;false,如果已经开始了,就不终止了;
    24             s.isDone();//是否已完成
    25             s.isCancelled();// 是否已经被取消
    26 
    27             String result = s.get();// 获取执行的结果,如果任务尚未执行完成,有可能会阻塞一段时间
    28             String result2 = s.get(3, TimeUnit.SECONDS);//最多等待3秒,get的重载方法,因为有可能会阻塞,阻塞的时长不定,所以提供一个重载方法,指定阻塞的最大时间;
    29 
    30             //````如果你只是想执行任务,不想要返回值,那么,用execute
    31             Runnable runnable = new Runnable() {
    32                 @Override
    33                 public void run() {
    34                     Log.d("hahaha", "假装这里有代码");
    35                 }
    36             };
    37             CustomThreadPool.getInstance().execute(runnable);
    38 
    39         } catch (InterruptedException e) {
    40             e.printStackTrace();
    41         } catch (ExecutionException e) {
    42             e.printStackTrace();
    43         } catch (TimeoutException e) {
    44             e.printStackTrace();
    45         }
    46     }
  • 相关阅读:
    json
    ajax
    oracle 分页查询
    NuGet使用
    【EF】Entity Framework使用
    【mssql】增删改查笔记
    【mysql】知识点
    【angularJS】学习笔记
    C# Ninject使用
    【CSS】Table样式
  • 原文地址:https://www.cnblogs.com/hankzhouAndroid/p/9505423.html
Copyright © 2020-2023  润新知