开发者

Android开发ThreadPoolExecutor与自定义线程池详解

目录
  • 概述
  • ThreadPoolExecutor 类
    • 构造方法
    • 线程池原理
      • 无界和有界队列:
      • 存入:
      • 获取:
    • 创建线程池的构造方法
    • 自定义线程池
      • 1、编写任务类
        • 2、编写线程类,用于执行任务
          • 3、编写线程池类,用于管理线程的执行
            • 4、测试
            • 文末

              概述

              1、ThreadPoolExwww.devze.comecutor作为Java.util.concurrent包对外提供基础实现,以内部线程池的形式对外提供管理任务执行,线程调度,线程池管理等等服务;

              2、Executors方法提供的线程服务,都是通过参数设置来实现不同的线程池机制。

              3、先来了解其线程池管理的机制,有助于正确使用,避免错误使用导致严重故障。同时可以根据自己的需求实现自己的线程池

              ThreadPoolExecutor 类

              构造方法

              public ThreadPzSvLGVSSoolExecutor(
              	int corePoolSize,					//核心线程数量:如果当前运行的线程数量没有达到 corePoolSize,则新建一个线程,否则加入到任务队列中
              	int maximumPoolSize,				//最大线程数:当前系统最多存在的线程数
              	long keepAliveTime,					//最大空闲时间:线程空闲的最大时间,超出时间该线程会销毁;设置allowCodeThreadTimeOut(true/false),可控制核心线程是否销毁,默认false 表示允许核心线程即使超过最大线程时间也不会销毁
              	TimeUnit unit,						//时间单位:	线程空闲的最大时间的单位
              	blockingQueue<Runnable> workQueue,	//任务队列:	核心线程数量满了之后,提交的任务加入到队列中,等待核心线程数减少后再去创建线程;当任务队列已满,但没有达到最大线程数时,则新建非核心线程
              	ThreadFactory threadFactory,		//线程工厂:	自定义线程的创建
              	RejectedExecutionHandler handler	//饱和处理机制:当任务队列已满且达到最大线程数时,采取的措施
              )	
              

              线程池原理

              线程池底层使用**堵塞式队列 BlockingQueue **。

              队列遵从:先进先出,后进后出原则。 阻塞队列(BlockingQueue)和非阻塞队列(ConcurrentLinkedQueue )区别:

              无界和有界队列:

              ConcurrentLinkedQueue 是无界队列,不用设置长度,可以随便存放值(其实是jdk伪造的,最大长度是Integer的最大值) BlockingQueue 是有界队列,需要设置长度。 注意:如果BlockingQueue 不设置等待时间就是非阻塞队列

              存入:

              非阻塞队列:如果存放超出了队列总数,添加不进去,就会丢失。 阻塞队列:如果存放超出了队列总数,进行等待,直到有队列出列,或者超时设置的等待时间)

              获取:

              非阻塞队列:如果为空时,返回空。 阻塞队列:如果为空时,进行等待,直到有新的队列入列,或者超过设置的等待时间

              创建线程池的构造方法

              ThreadPoolExecutor(int corePoolSize,
                                 int maximumPoolSize,
                                 long keepAliveTime,
                                 TimeUnit unit,
                                 BlockingQueue<Runnable> workQueue)
              
              • ThreadPoolExecutor
              • 参数说明
              • 核心线程大小(corePoolSize)
              • 最大线程大小(maximumPoolSize)
              • 终止时间(keepAliveTime)
              • Unit 超时时间
              • workQueue 线程容器

              自定义线程池

              1、编写任务类

              public class MyTask implements Runnable{
              	//任务id
              	private int id;
              	public MyTask(int id){
              	    this.id=id;
              	}
              	@Override
              	public void run() {
              	    String name=Thread.currentThread().getName();
              	    System.out.println("线程:"+name+"-->即将执行任务"+id);
              	    try {
              	        Thread.sleep(200);
              	    } catch (InterruptedException e) {
              	        e.printStackTrace();
              	    }
              	    System.out.println("线程:"+name+"执行完成"+id);
              	}
              	@Override
              	public String toString() {
              	    return "MyTask{" +
              	            "id=" + id +
              	            '}';
              	}
              }
              

              2、编写线程类,用于执行任务

              public class MyThread extends  Thread{
                  private List<Runnable> tasks;
                  public MyThread(String name, List<Runnable> tasks){
                      super(name);
                      this.tasks=tasks;
                  }
                  @Override
                  public void run() {
                      while (tasks.size() > 0){
                          Runnable r= tasks.remove(0);
                          r.run();
                      }
                  }
              }
              

              3、编写线程池类,用于管理线程的执行

              public class MyThreadPool {
                  private List<Runnable>  tasks = Collections.synchronizedList(new LinkedList<>());
                  /**
                   * 当前线程数
                   */
                  priv开发者_Go教程ate int num;
                  /**
                   * 核心线程数
                   */
                  private int corePoolSize;
                  /**
                   * 最大线程数
                   */
                  private int maxSize;
                  /**
                   * 任务队列数
                   */
                  private int workSize;
                  public MyThreadPool(int corePoolSize, int maxSize, int workSize) {
                      this.corzSvLGVSSePoolSize = corePoolSize;
                      this.maxSize = maxSize;
                      this.workSize = workSize;
                  }
                  /**
                   * 提交任务
                   */
                  public void submit(Runnable r){
                      if (tasks.size()>=workSize && tasks.size() > maxSize){
                          System.out.println("任务:"+r+"被丢弃了");
                      }else{
                   http://www.devze.com       tasks.add(r);
                          execTask(r);
                      }
                  }
                  public void execTask(Runnable r){
                      if (corePoolSize > num){
                          new MyThread("核心线程:"+num,tasks).start();
                          num++;
                      }else  if(num < maxSize){
                          new MyThread("非核心线程:"+num,tasks).start();
                          num++;
                      }else{
                          System.out.println("任务:"+r+"被缓存了");
                      }
                  }
              }
              

              4、测试

              public class Demo {
                  public static void main(String[] args) {
                      MyThreadPool myThreadPool = new MyThreadPool(2, 4, 20);
                      for (int i =0;i< 300;i++){
                          MyTask myTask = new MyTask(i);
                          myThreadPool.submit(myTask);
                      }
                  }
              }
              

              以上就是android开发中ThreadPoolExecutor与自定义线程池;

              文末

              1、用ThreadPoolExecutor自定义线程池,看线程是的用途,如果任务量不大,可以用无界队列,如果任务量非常大,要用有界队列,防止OOM

              2、如果任务量很大,还要求每个任务都处理成功,要对提交的任务进行阻塞提交,重写拒绝机制,改为阻塞提交。保证不抛弃一个任务

              3、最大线程数一般设为2N+1最好,N是CPU核数

              4、核心线程zSvLGVSS数,看应用,如果是任务,一天跑一次,设置为0,合适,因为跑完就停掉了,如果是常用线程池,看任务量,是保留一个核心还是几个核心线程数

              5、如果要获取任务执行结果,用CompletionService,但是注意,获取任务的结果的要重新开一个线程获取,如果在主线程获取,就要等任务都提交后才获取,就会阻塞大量任务结果,队列过大OOM,所以最好异步开个线程获取结果

              以上就是Android开发ThreadPoolExecutor与自定义线程池详解的详细内容,更多关于Android ThreadPoolExecutor的资料请关注我们其它相关文章!

              0

              上一篇:

              下一篇:

              精彩评论

              暂无评论...
              验证码 换一张
              取 消

              最新开发

              开发排行榜