java线程池详解 官网,Java线程池详解

  java线程池详解 官网,Java线程池详解

  

  线程池概述

  1.线程池是管理线程的池,可以减少创建和销毁线程所造成的资源消耗。

  因为线程实际上是一个对象,创建一个对象需要经历类加载过程,销毁一个对象,经历GC垃圾回收过程,这些都需要资源开销。

  2.提高反应速度,任务已经到了。相比从线程池中抓取线程,自己创建线程肯定要慢很多。

  3.重用。线程用完了,就放回池中,这样就达到了重用的效果。

  (推荐视频:java视频教程)

  线程池执行

  打个比方。

  核心线程被比作公司的正式员工。

  非核心线程被比作外包员工。

  阻塞队列被比作需求池。

  提交任务就像是自讨苦吃。

  如何解决写爬虫IP受阻的问题?立即使用。

  正式执行

  public thread pool executor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit单位,

  BlockingQueueRunnable工作队列,

  线程工厂线程工厂,

  ReordexecutionHandler处理程序)Corepoolsize核心线程

  maximumPoolSize线程池中的最大线程数

  KeepAliveTime空闲线程生存期

  单位时间线程空闲生存期单位

  工作队列保存任务的阻塞队列。

  螺纹工厂

  处理程序饱和策略当一个任务提交后,线程池中存活的核心线程数小于线程数corePoolSize时,线程池会创建一个核心线程来处理提交的任务。

  如果线程池中的核心线程数已满,即线程数已经等于corePoolSize,一个新提交的任务将被放入任务队列workQueue等待执行。

  当线程池中存活的线程数已经等于corePoolSize,且任务队列的workQueue已满时,判断线程数是否达到maximumPoolSize,即最大线程数是否已满。如果没有,创建一个非核心线程来执行提交的任务。

  如果当前线程数达到maximumPoolSize,并且有新任务到来,将直接采用拒绝策略。

  几种饱和策略

  AbortPolicy抛出异常,默认情况下

  丢弃策略直接丢弃任务。

  DiscardOldestPolicy会丢弃队列中最早的任务,并继续将当前任务提交给线程池。

  CallerRunsPolicy被移交给进行线程池调用的线程,用于处理线程池异常处理

  因为调用线程池处理任务过程中的异常可能会被线程池捕获,任务的执行可能是察觉不到的,所以我们需要考虑线程池的异常。

  方法1:

  @测试

  public void test1()引发异常{

  ExecutorService ExecutorService=executors . newfixedthreadpool(5);

  for(int I=0;i5;i ) {

  executorservice . submit(new Runnable(){

  @覆盖

  公共无效运行(){

  尝试{

   name: Thread.currentThread()。getName());

  对象a=null

  system . out . println(a . hashcode());

  } catch(异常e) {

  system . out . println(e);

  }

  }

  });

  }

  }方法二:

  @测试

  public void test2()引发异常{

  ExecutorService ExecutorService=executors . newfixedthreadpool(5);

  for(int I=0;i 20i ) {

  未来?future=executorservice . submit(new Runnable(){

  @覆盖

  公共无效运行(){

   name: Thread.currentThread()。getName());

  对象a=null

  system . out . println(a . hashcode());

  }

  });

  尝试{

  future . get();

  } catch(异常e) {

  system . out . println(e);

  }

  }

  }线程池的工作队列

   ArrayBlockingQueue

   LinkedBlockingQueue

  同步队列

  延迟队列

   PriorityBlockingQueue

  ==ArrayBlockingQueue==

  初始化具有一定容量的阵列

  使用重入锁,默认为不公平锁。入队和出队共享一个锁,这是互斥的。

  是有界设计。如果容量已满,则无法继续添加元素,除非删除一些元素。

  使用时,开辟一个连续的记忆。如果初始化容量过大,容易浪费资源;如果太小,很容易添加失败。

  ==LinkedBlockingQueue==

  使用链表数据结构

  不连续的存储空间

  使用两个重入锁分别控制元素的入队和出队,使用条件在线程间唤醒和等待。

  有界,容量为整数。默认构造方法中的MAX_VALUE。

  ==SynchronousQueue==

  内部容量为0。

  每次删除都要等待插入操作。

  每次插入时等待删除。

  一旦有了插入线程和移除线程,元素就被快速地从插入线程转移到移除线程。这个容器相当于一个通道,本身不存储元素。

  在多任务队列中,是处理任务最快的方式。

  ==PriorityBlockingQueue==

  无边的设计,但容量其实取决于系统资源的影响。

  添加元素,如果超过1,输入优先顺序。

  ==延迟队列==

  无限设计

  加(放)不堵,拆堵。

  所有元素都有失效时间。

   Take元素只有过期才会被取出。

  常用的线程池

   newFixedThreadPool(具有固定数量线程的线程池)

   newCachedThreadPool(可缓存线程的线程池)

   newSingleThreadExecutor(单线程的线程池)

   newScheduledThreadPool(用于常规和定期执行的线程池)

  ==newFixedThreadPool==

  public static ExecutorService newFixedThreadPool(int nThreads){

  返回新的ThreadPoolExecutor(nThreads,nThreads,

  0L,时间单位。毫秒,

  new LinkedBlockingQueueRunnable());

  }特点

  1.核心线程的数量与最大线程数量相同。

  2.没有所谓的非空闲时间,即keepAliveTime为0

  3.阻塞队列是LinkedBlockingQueue的无界队列

  工作机制:

  提交任务。

  如果线程数少于核心线程数,则创建核心线程来执行任务。

  如果线程数等于核心线程数,则将任务添加到LinkedBlockingQueue的阻塞队列中。

  如果线程完成任务,阻塞队列获取任务,继续执行。

  ==newCachedThreadPool==

  public static ExecutorService newCachedThreadPool(){

  返回新的ThreadPoolExecutor(0,整数。最大值,

  60L,时间单位。秒,

  new SynchronousQueueRunnable());

  }线程池特点

  核心线程数为0。

  最大线程数为整数。最大值

  阻塞队列是SynchronousQueue。

  非核心线程的空闲存活时间为60秒。

  工作机制:

  提交任务。

  因为没有核心线程,所以任务直接加入SynchronousQueue队列。

  判断是否有空闲线程,如果有,取出任务执行。

  如果没有空闲线程,则创建一个新线程来执行。

  完成任务的线程还能活60秒。如果它在这期间接到任务,就可以继续活下去;不然就毁了。

  使用场景

  用于并发执行大量短期小任务。

  ==newSingleThreadExecutor==

  线程池特点

  核心线程数为1。

  最大线程数也是1。

  阻塞队列被链接阻塞队列

   keepAliveTime为0。

  公共静态执行器服务newSingleThreadExecutor(ThreadFactory ThreadFactory){

  返回新的FinalizableDelegatedExecutorService

  (新的ThreadPoolExecutor(1,1,

  0L,时间单位。毫秒,

  新LinkedBlockingQueueRunnable(),

  thread factory));

  }工作机制

  提交任务。

  线程池中有线程吗?如果没有,请创建一个新线程来执行该任务。

  如果是,将任务添加到阻塞队列。

  当前唯一的线程,从队列中取任务,执行一个,然后继续取。一个人(一根线)没日没夜的工作。

  使用场景

  它适用于串行执行任务的场景,一次执行一个任务。

  ==newScheduledThreadPool==

  线程池特点

  public scheduled threadpoolexecutor(int corePoolSize){

  super(corePoolSize,整数。MAX_VALUE,0,纳秒,new DelayedWorkQueue());

  }最大线程数为整数。最大值

  阻塞队列是DelayedWorkQueue。

   keepAliveTime为0。

   scheduleAtFixedRate():以一定的速率周期性执行。

   scheduleWithFixedDelay():在一定延迟后执行。

  工作机制

  添加任务。

  线程池中的线程从延迟队列中获取任务。

  线程从DelayQueue中获取时间大于等于当前时间的任务。

  执行后,修改该任务下次执行的时间。

  该任务被放回延迟队列。

  scheduleWithFixedDelay

  无论任务执行多长时间,第一个任务完成后,延迟指定时间再开始第二个任务。

  scheduleAtFixedRate

  当任务执行时间小于间隔时间时,程序将以启动时间为基础每隔指定时间执行一次,不受任务执行时间的影响。

  当任务执行时间长于间隔时间时,该方法不会重新启动一个新的任务执行,而是等待原任务完成后,立即启动下一个任务执行。此时,执行间隔已被打乱。

  本文来自我们,java教程专栏,欢迎学习!以上是java线程池的详细内容。更多请关注我们的其他相关文章!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: