线程池的基本原理(线程池的概念),本文通过数据整理汇集了线程池的基本原理(线程池的概念)相关信息,下面一起看看。

第一,为什么要用线程池来减少资源消耗。通过重用创建的线程来减少创建和销毁线程所造成的消耗。

提高响应速度。当任务到达时,它可以立即执行,而不需要等待线程被创建。

提高线程的可管理性。线程是稀缺资源。如果无限制地创建它们,不仅会消耗系统资源,还会降低系统的稳定性。使用线程池可以进行统一分配、调优和监控。

二、ThreadPoolExecutor线程池类参数详细参数描述corePoolSize核心线程数、线程池维护线程最小数maximumPoolSize线程池维护线程最大数keepAliveTime线程池除核心线程外其他线程的最长空闲时间,超过此时间的空闲线程将被unitkeepAliveTime单元销毁。TimeUnit中的几个静态属性:纳秒,微秒,毫秒,threadFactory线程工厂,线程池使用的任务缓冲队列,用于创建线程。通常,默认的处理程序线程池可以用来处理被拒绝的任务。当一个线程池任务处理不了的时候(你觉得处理不了的时候,后面会讲到),可以用handler指定的策略来处理。ThreadPoolExecutor提供了四种策略:

ThreadPoolExecutor。AbortPolicy:丢弃任务并引发RejectedExecutionException异常;这也是默认的处理方法。threadpooleexecutor . Discard policy:放弃任务,但不抛出异常。线程池执行器。DiscardOldestPolicy:丢弃队列前面的任务,然后尝试再次执行该任务(重复这个过程)。线程池执行器。CallerrunsPolicy:调用线程处理这个任务。您可以通过实现RejectedExecutionHandler的接口来自定义处理方法。

三、线程池任务执行1。添加执行任务submit()这个方法返回一个Future对象,可以执行返回值的线程;或者执行一个您想随时取消的线程。Future对象的get()方法获取返回值。Future对象的Cancel(true/false)取消任务,如果任务尚未开始或完成,则返回false。该参数指示是否中断正在执行的线程execute()没有返回值。2.线程池任务提交过程。如果此时线程池中的数量小于corePoolSize,那么即使线程池中的所有线程都是空闲的,也应该创建一个新的线程来处理添加的任务。

2.2.如果此时线程池中的数量等于corePoolSize,但是缓冲区队列workQueue未满,那么将任务放入缓冲区队列。

2.3.如果此时线程池中的数量大于或等于corePoolSize,缓冲区队列workQueue已满,线程池中的数量小于maximumPoolSize,则创建一个新线程来处理添加的任务。

2.4.如果此时线程池中的数量大于corePoolSize,缓冲区队列workQueue已满,线程池中的数量等于maximumPoolSize,则该任务由handler指定的策略处理。

2.5.当线程池中的线程数大于corePoolSize时,如果一个线程的空闲时间超过keepAliveTime,该线程将被终止。这样,线程池可以动态地调整池中线程的数量。

即处理任务判断的优先级是核心线程corePoolSize、任务队列workQueue、最大线程maximumPoolSize。如果三个都满了,处理被拒绝的任务。

注意:

当workQueue使用无限队列时,maximumPoolSize参数变得没有意义,比如new LinkedBlockingQueue()或NewArrayBlockingQueue(integer . max _ value);使用SynchronousQueue时,任务将不会排队,因为队列没有容量。如果线程池中没有空闲线程,将立即创建一个新线程来接收任务。应将MaximumPoolSize设置得更大。当核心数和最大线程数相等时,KeepAliveTime不起作用。3.线程池已关闭。3.1.shutdown()不接受新任务,但会处理添加的任务。3.2.shutdownNow()不接受新任务,不处理添加的任务,并中断正在工作的任务。

4.公共队列介绍4.1。ArrayBlockingQueue:这是一个由数组实现的固定容量的有界阻塞队列。

4.2.SynchronousQueue:没有容量来缓存数据;每一次放必须等待一次拿;如果poll()或take()中没有其他线程,Offer()将返回false。

4.3.LinkedBlockingQueue:这是一个默认的无界阻塞队列,由单个链表实现。LinkedBlockingQueue提供了可选的有界构造函数,当没有指定容量时,容量为整数。默认为MAX_VALUE。

队列操作:

方法add添加一个元电缆;如果队列已满,抛出异常remove移除并返回队列头的元素;如果队列为空,抛出一个异常offer来添加一个元素并返回true如果队列已满,则返回falsepoll以移除并返回队列头的元素;如果队列为空,则返回nullput以添加一个元素;如果队列已满,block take移除并返回队列头的元素;如果队列为空,阻止元素返回队列头的元素;如果队列为空,抛出异常peek返回队列头的元素;如果队列为空,则返回null5。执行者线程工厂类1。执行人。NewCachedThreadPool();描述:创建一个可缓存的线程池。如果线程池的长度超过了处理需要,可以灵活地回收空闲线程。如果没有回收,你可以创建一个新的线程。内部实现:新线程池执行器(0,integer.max _ value,60L,time unit.seconds,new synchronousqueuerunnable());/可运行

2.executors . newfixedthreadpool(int);注意:创建一个定长线程池,可以控制并发线程的最大数量,多余的线程会在队列中等待。内部实现:新线程池执行器(NTHREADS,NTHREADS,0L,时间单位。毫秒,New LinkedBlockingQueueRunable());/可运行

3.executors . newsinglethreadexecutor();描述:创建一个单线程线程池,该线程池将只使用唯一的工作线程来执行任务,并确保所有任务按顺序执行。内部实现:新线程池执行器(1,1,0L,timeunit.milliseconds,new linkedblocking queuerunnable())/runnable

4.executors . newscheduledthreadpool(int);描述:创建一个固定长度的线程池来支持计划的和周期性的任务执行。内部实现:新的scheduledthreadpoolexecutor(corepoolsize)

[附件]阿里巴巴Java开发手册中线程池的使用规范

【强制】创建线程或线程池时请指定一个有意义的线程名,以便出错时便于回溯。示例:public类timertask thread extends thread { public timertask thread(){ super . set name(' timertask thread ');}}【强制】线程资源必须通过线程池提供,不允许在应用本身显式创建线程。注意:使用线程池的好处是减少创建和销毁线程的时间和系统资源的开销,解决资源不足的问题。如果不使用线程池,可能会导致系统创建大量相似的线程,造成内存消耗或“过度切换”。

【强制】线程池不允许使用Executors创建,而是通过ThreadPoolExecutor的方式创建。这种处理方式让写线程池的同学更加清楚线程池的运行规则,避免了资源枯竭的风险。

说明:执行器返回线程池对象的缺点如下:1) FixedThreadPool和SingleThreadPool:允许的请求队列长度为整数。MAX_VALUE,可能会堆积大量请求,导致OOM。2) CachedThreadPool和ScheduledThreadPool:允许的创建线程数是整数。MAX_VALUE,可能会创建大量线程,导致OOM。

6.总结一下ThreadPoolExecutor通过几个核心参数定义了不同类型的线程池,适用于不同的使用场景;其中,任务提交时会依次判断corePoolSize、workQueque、maximumPoolSize,不同的状态会区别对待。技术领域太深,如果不是日常使用,有些知识点过一段时间就差不多忘了。所以要定期复习总结,巩固自己的技术基础。

更多线程池的基本原理(线程池的概念)相关信息请关注本站,本文仅仅做为展示!