关于Java线程池详解(二)

一.为什么要用线程池?

1.减少资源的开销 ;

2.减少了每次创建线程、销毁线程的开销;

3.提高响应速度 ,每次请求到来时,由于线程的创建已经完成,故可以直接执行任务,因此提高了响应速度。

提高线程的可管理性 ,线程是一种稀缺资源,若不加以限制,不仅会占用大量资源,而且会影响系统的稳定性。

因此,线程池可以对线程的创建与停止、线程数量等等因素加以控制,使得线程在一种可控的范围内运行,不仅能保证系统稳定运行,而且方便性能调优。

二.Executor框架中的所有类可以分成三类:

1.任务:

任务有两种类型:Runnable和Callable。

2.任务执行器:

Executor框架最核心的接口是Executor,它表示任务的执行器。

Executor的子接口为ExecutorService。

ExecutorService有两大实现类:ThreadPoolExecutor和ScheduledThreadPoolExecutor。

3.执行结果:

Future接口表示异步的执行结果,它的实现类为FutureTask。

三.4种类型的线程池:

1. FixedThreadPool 定长线程池:

它是一种固定大小的线程池;

corePoolSize和maximunPoolSize都为用户设定的线程数量nThreads;

keepAliveTime为0,意味着一旦有多余的空闲线程,就会被立即停止掉;但这里keepAliveTime无效;

阻塞队列采用了LinkedBlockingQueue,它是一个无界队列;

由于阻塞队列是一个无界队列,因此永远不可能拒绝任务;

由于采用了无界队列,实际线程数量将永远维持在nThreads,因此maximumPoolSize和keepAliveTime将无效。

2. CachedThreadPool 可缓存线程池:

它是一个可以无限扩大的线程池;

它比较适合处理执行时间比较小的任务;

corePoolSize为0,maximumPoolSize为无限大,意味着线程数量可以无限大;

keepAliveTime为60S,意味着线程空闲时间超过60S就会被杀死;

采用SynchronousQueue装等待的任务,这个阻塞队列没有存储空间,这意味着只要有请求到来,就必须要找到一条工作线程处理他,如果当前没有空闲的线程,那么就会再创建一条新的线程。

3. SingleThreadExecutor  单一线程池:

它只会创建一条工作线程处理任务;

采用的阻塞队列为LinkedBlockingQueue;

4. ScheduledThreadPool  可调度的线程池

四. 线程池的处理流

一个线程从被提交(submit)到执行共经历以下流程:

1.线程池判断核心线程池里是的线程是否都在执行任务,如果不是,则创建一个新的工作线程来执行任务。如果核心线程池里的线程都在执行任务,则进入下一个流程;

2.线程池判断工作队列是否已满。如果工作队列没有满,则将新提交的任务储存在这个工作队列里。如果工作队列满了,则进入下一个流程。

3.线程池判断其内部线程是否都处于工作状态。如果没有,则创建一个新的工作线程来执行任务。如果已满了,则交给饱和策略来处理这个任务。

线程池在执行execute方法时,主要有以下四种情况:

1.如果当前运行的线程少于corePoolSize,则创建新线程来执行任务(需要获得全局锁)

2.如果运行的线程等于或多于corePoolSize ,则将任务加入BlockingQueue

3.如果无法将任务加入BlockingQueue(队列已满),则创建新的线程来处理任务(需要获得全局锁)

4.如果创建新线程将使当前运行的线程超出maxiumPoolSize,任务将被拒绝,并调用RejectedExecutionHandler.rejectedExecution()方法。

线程池采取上述的流程进行设计是为了减少获取全局锁的次数。在线程池完成预热(当前运行的线程数大于或等于corePoolSize)之后,几乎所有的excute方法调用都执行步骤2。

原文地址:https://www.cnblogs.com/ZJOE80/p/12562201.html

时间: 2025-01-10 06:03:59

关于Java线程池详解(二)的相关文章

Java线程池详解(二)

一.前言 在总结了线程池的一些原理及实现细节之后,产出了一篇文章:Java线程池详解(一),后面的(一)是在本文出现之后加上的,而本文就成了(二).因为在写完第一篇关于java线程池的文章之后,越发觉得还有太多内容需要补充,每次都是修修补补,总觉得还缺点什么.在第一篇中,我着重描述了java线程池的原理以及它的实现,主要的点在于它是如何工作的.而本文的内容将更为上层,重点在于如何应用java线程池,算是对第一篇文章的一点补充,这样对于java线程池的学习和总结稍微完整一些. 使用过java线程池

【java线程系列】java线程系列之java线程池详解

一线程池的概念及为何需要线程池: 我们知道当我们自己创建一个线程时如果该线程执行完任务后就进入死亡状态,这样如果我们需要在次使用一个线程时得重新创建一个线程,但是线程的创建是要付出一定的代价的,如果在我们的程序中需要频繁使用线程,且每个线程执行的时间很短,短到几乎小于线程创建及销毁的时间那么代价将会更大,如:服务器应用程序中经常出现的情况是:单个任务处理的时间很短而请求的数目却是巨大的.显然如果频繁的创建销毁线程效率将非常低. 那么我们能否让一个线程可以复用,即当一个线程执行完后不销毁该线程,而

Java线程池 详解(图解)

来源:www.jianshu.com/p/098819be088c 前言   Java中的线程池十分重要,无论是在实际应用中还是应对面试 一.线程池原理 1.1 使用线程池的好处 第一:降低资源消耗.通过重复利用已创建的线程降低线程创建和销毁造成的消耗. 第二:提高响应速度.当任务到达时,任务可以不需要等到线程创建就能立即执行. 第三:提高线程的可管理性.线程是稀缺资源,如果无限制地创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一分配.调优和监控. 1.2 线程池的实现原理

java线程池详解一

1.为什么要用线程池技术 诸如Web服务器.数据库服务器.文件服务器或邮件服务器之类的许多服务器应用程序都面向处理来自某些远程来源的大量短小的任务.请求以某种方式到达服务器,这种方式可能是通过网络协议(例如 HTTP.FTP 或 POP).通过 JMS 队列或者可能通过轮询数据库.不管请求如何到达,服务器应用程序中经常出现的情况是:单个任务处理的时间很短而请求的数目却是巨大的. 构建服务器应用程序的一个过于简单的模型应该是:每当一个请求到达就创建一个新线程,然后在新线程中为请求服务.实际上,对于

Java线程池详解及实例

前言 多线程的异步执行方式,虽然能够最大限度发挥多核计算机的计算能力,但是如果不加控制,反而会对系统造成负担.线程本身也要占用内存空间,大量的线程会占用内存资源并且可能会导致Out of Memory.即便没有这样的情况,大量的线程回收也会给GC带来很大的压力. 为了避免重复的创建线程,线程池的出现可以让线程进行复用.通俗点讲,当有工作来,就会向线程池拿一个线程,当工作完成后,并不是直接关闭线程,而是将这个线程归还给线程池供其他任务使用. 接下来从总体到细致的方式,来共同探讨线程池. 总体的架构

Java线程池详解

一.线程池初探 所谓线程池,就是将多个线程放在一个池子里面(所谓池化技术),然后需要线程的时候不是创建一个线程,而是从线程池里面获取一个可用的线程,然后执行我们的任务.线程池的关键在于它为我们管理了多个线程,我们不需要关心如何创建线程,我们只需要关系我们的核心业务,然后需要线程来执行任务的时候从线程 http://pic.cnhubei.com/space.php?uid=1913&do=album&id=1109585http://pic.cnhubei.com/space.php?ui

Java 线程(多线程)详解

查看了许多书籍,网上的博客,现在我来说一下有关于我对线程的详解,有不对的欢迎指正. 一. 线程的生命周期: 程序有自己的一个生命周期,线程也不例外,也有自己的生命周期.查看许多书籍或者网上资料,发现了一件很有趣的事情,那就是它们对线程的生命周期不是唯一.有两种或者以上的线程生命周期. 第一种线程生命周期线程状态转换图:一共5个状态:新建,就绪,运行,阻塞和结束   图 1 第二种生命周期图:一共6个状态:New,Runnable,Blocked,Waiting,Timed Waiting,Ter

java - jdk线程池详解

线程池参数详解 public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) 参数 说明 corePoolSize 表示常驻核心线程数量. maximumPoolS

Java自定义线程池详解

自定义线程池的核心:ThreadPoolExecutor 为了更好的控制多线程,JDK提供了一套线程框架Executor,帮助开发人员有效的进行线程控制,其中在java.util.concurrent包下,是JDK并发包的核心,比如我们熟知的Executors.Executors扮演着线程工厂的角色,我们通过它可以创建特定功能的线程池,而这些线程池背后的就是:ThreadPoolExecutor.那么下面我们来具体分析下它. 构造ThreadPoolExecutor public ThreadP