线程数

线程池是怎样工作的

筅森魡賤 提交于 2019-12-02 19:14:30
我们在工作中或多或少都使用过线程池,但是为什么要使用线程池呢?从他的名字中我们就应该知道,线程池使用了一种池化技术,和很多其他池化技术一样,都是为了更高效的利用资源,例如链接池,内存池等等。 数据库链接是一种很昂贵的资源,创建和销毁都需要付出高昂的代价,为了避免频繁的创建数据库链接,所以产生了链接池技术。优先在池子中创建一批数据库链接,有需要访问数据库时,直接到池子中去获取一个可用的链接,使用完了之后再归还到链接池中去。 同样的,线程也是一种宝贵的资源,并且也是一种有限的资源,创建和销毁线程也同样需要付出不菲的代价。我们所有的代码都是由一个一个的线程支撑起来的,如今的芯片架构也决定了我们必须编写多线程执行的程序,以获取最高的程序性能。 那么怎样高效的管理多线程之间的分工与协作就成了一个关键问题,Doug Lea 大神为我们设计并实现了一款线程池工具,通过该工具就可以实现多线程的能力,并实现任务的高效执行与调度。 为了正确合理的使用线程池工具,我们有必要对线程池的原理进行了解。 本篇文章主要从三个方面来对线程池进行分析:线程池状态、重要属性、工作流程。 线程池状态 首先线程池是有状态的,这些状态标识这线程池内部的一些运行情况,线程池的开启到关闭的过程就是线程池状态的一个流转的过程。 线程池共有五种状态: 状态 含义 RUNNING 运行状态,该状态下线程池可以接受新的任务

8核、6核、4核、双核CPU是什么意思

那年仲夏 提交于 2019-12-02 19:06:58
对于初学者来说,CPU是什么、什么是双核、4核、6核、8核等。下面,就以上的问题,我们做出一一解答。 概念:CPU是什么、做什么用、一般CPU是接在哪里的,我们先来看看CPU是什么,CPU既中央处理器、电脑中一个最重要,最核心的东西,市面上能买到的CPU只有两种,一种是INTEL公司生产的,另一种是AMD公司生产的。如图1-1: 上图分别是INTEL和AMD公司两个厂家生产的CPU,CPU主要的工作就是处理和运算数据,所以,CPU运算速度、主频、缓存、核心数,这几个参数就决定了CPU的好坏,CPU的主频越高、缓存越大、核心数越多,这样的CPU运转速度就很快,处理图形图像文件起来,速度就越快,这种CPU的价格就比较贵,下面,我找两款CPU对比来说说他们的好坏。如图1-2: 我们来看看INTEL的CPU G2020和E3-1230这两款CPU的参数对比一下,G2020的主频:2.9G、缓存是一级缓存:128KB、二级缓存:512KB、三级缓存:3MB,核心数:2个,线程数:2个。我们在来看看E3-1230,E3-1230的主频:3.2G、缓存是一级缓存:256KB、二级缓存:1MB、三级缓存:8MB,核心数:4个,线程数:8个。从这两个CPU的参数来看,我们很明显的能够看出来,E3-1230的CPU比G2020的CPU要好很多,那么E3-1230这个CPU安装在我们的电脑上面

Java服务MQ消息队列容灾方案

烈酒焚心 提交于 2019-12-02 18:58:12
背景介绍 在前一段时间线上出现过一次事故,一个非常重要的消息生产者服务,由于MQ出现问题,消息大量积压,导致了该服务线程被打满,外部请求返回502,服务采用Springboot搭建,使用Springboot的Tomcat容器。 原因分析 消息的生产者服务是一个高并发量的服务,接受外部方的接口调用,并将消息推送至MQ,调用流程示意图如下: 而事故当天的情况是,MQ消息大量积压,基本等同于MQ挂掉, 大量的请求积压在推送消息到MQ的地方,导致外部的大量的请求在Tomcat的线程池积压,当Tomcat的线程池全部被打满后,服务不能再接受新的请求进入,导致抛出大量的502错误。 容灾方案分析 一、发送消息超时时间设定 首先可以想到的是,在MQ发送消息处,设置推送消息的超时时间,超过超时时间,认为消息发送失败,将消息写入文件中,当时这个方案并没有根本上解决,如果MQ挂掉,Tomcat不被打满的问题,虽然可以解决目前的生产场景的情况,但是当后续请求量更大时候,不能保证Tomcat不被打满,同时,消息推送的超时时间的设定也不好进行把握,如果由于网络波动或其他情况,导致消息推送慢,但是是可以推送成功的,但是万一超过了超时时间,消息直接不会发送,反而会影响目前的业务逻辑。 二、调整Tomcat线程池大小 事故的起因是因为Tomcat被打满,那调整Tomcat的线程池大小,调整大一些不就可以了吗

java 线程池的使用

瘦欲@ 提交于 2019-12-02 18:54:52
java 线程池的使用 1.线程池的概念 线程池:创建线程的生命周期包括创建、就绪,阻塞和销毁阶段,当我们要执行的任务比较小且频繁时,会导致重复的创建线程,避免资源的消耗。线程池中存放我们需要数量的 线程,使用已经创建好的线程去执行我们的操作,避免频繁的创建。 Java通过Executors提供四种线程池,分别为: newCachedThreadPool:创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。 newFixedThreadPool: 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。 newScheduledThreadPool: 创建一个定长线程池,支持定时及周期性任务执行。 newSingleThreadExecutor: 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。 2.为什要使用线程池? 1.单个的任务之多,可以使多个任务有序的执行 2.处理任务比较频繁,避免重复的创建和销毁线程,减少cpu和资源的使用 3.几种线程池具体的使用方法 newCachedThreadPool:可缓存的线程池的使用 ExecutorService cachedThreadPool = Executors.newCachedThreadPool(

Java线程池使用说明

廉价感情. 提交于 2019-12-02 18:54:04
前言 既然此篇文章提到了线程的问题,那博主就送大家一套学习视频 “java线程高并发实战教程” 在公众号内 回复 “线程” 即可获取 一、简介 线程的使用在java中占有极其重要的地位,在jdk1.4极其之前的jdk版本中,关于线程池的使用是极其简陋的。在jdk1.5之后这一情况有了很大的改观。Jdk1.5之后加入了java.util.concurrent包,这个包中主要介绍java中线程以及线程池的使用。为我们在开发中处理线程的问题提供了非常大的帮助。 二:线程池 线程池的作用: 线程池作用就是限制系统中执行线程的数量。 根据系统的环境情况,可以自动或手动设置线程数量,达到运行的最佳效果;少了浪费了系统资源,多了造成系统拥挤效率不高。用线程池控制线程数量,其他线程排队等候。一个任务执行完毕,再从队列的中取最前面的任务开始执行。若队列中没有等待进程,线程池的这一资源处于等待。当一个新任务需要运行时,如果线程池中有等待的工作线程,就可以开始运行了;否则进入等待队列。 为什么要用线程池? 减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务。 可以根据系统的承受能力,调整线程池中工作线线程的数目,防止因为消耗过多的内存,而把服务器累趴下(每个线程需要大约1MB内存,线程开的越多,消耗的内存也就越大,最后死机)。 Java里面线程池的顶级接口是Executor

Java线程池原理及使用

被刻印的时光 ゝ 提交于 2019-12-02 18:48:06
java中的线程池是运用场景最多的并发框架。在开发过程中,合理的使用线程池能够带来下面的一些好处: 1、降低资源的消耗。 2、提高响应速度。 3、提高线程的可管理型。 1.1、线程池ThreadPoolExecutor工作原理 讲解之前,我们先看一张原理图 ThreadPoolExecutor执行execute方法有4种情况: 1)如果当前运行的线程少于corePoolSize,则创建新的线程来执行任务。 2)如果运行的线程等于或者多余corePoolSize,则将任务加入BlockingQueue中,在等待队列中,等待有新的线程可以运行。 3)如果BlockingQueue队列满了,且没有超过maxPoolSize,则创建新的线程来处理任务。 4)如果创建的线程超过maxPoolSize,任务会拒绝,并调用RejectExecutionHandler.rejectedExecution()方法。 1.2、线程池的使用 1.2.1、线程池的创建 一般我们可以通过ThreadPoolExecutor来创建一个线程池。 在ThreadPoolExecutor类中提供了四个构造方法: public class ThreadPoolExecutor extends AbstractExecutorService { ..... public ThreadPoolExecutor(int

线程池原理分析

左心房为你撑大大i 提交于 2019-12-02 18:45:32
问题导向 实现一个线程池,线程池调优 问题: 怎么设计一个线程池? 怎么管理线程的创建和状态? https://segmentfault.com/a/1190000015352777 怎么回收停止一个线程? 怎么去复用线程? 等待队列中的任务满了怎么办? 为什么要引入线程池? 降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。 提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。 提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。 线程池框架? Executor: 所有线程池的接口,只有一个方法。 ExecutorService: 增加Executor的行为,是Executor实现类的最直接接口。 Executors: 提供了一系列工厂方法用于创先线程池,返回的线程池都实现了ExecutorService 接口。 ThreadPoolExecutor:线程池的具体实现类,一般用的各种线程池都是基于这个类实现的。 public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable>

java线程池原理,常见线程池

落爺英雄遲暮 提交于 2019-12-02 18:42:19
java线程池原理 Executors类提供了FixedThreadPool、CachedThreadPool等线程池对象,都是基于ThreadPoolExecutor产生的。 Executor接口定义了execute(),子接口ExecutorService又定义了submit(),抽象类AbstractExecutorService继承了该子接口,调用execute()实现了submit(),ThreadPoolExecutor继承AbstractExecutorService接口,实现了execute()。 ThreadPoolExecutor主要持有一个HashSet用于存储worker,持有一个阻塞队列用于存储待执行的任务(Runnable/Callable)。如果HashSet未达到指定大小,接到任务时立即创建worker,否则将任务存入阻塞队列。创建worker时启动一个线程,构造worker时传入的第一个Runnale开始执行,执行完后通过getTask()从阻塞队列中取出任务继续执行。 public class ThreadPoolExecutor extends AbstractExecutorService { //持有阻塞队列和HashSet,分别存放排队的任务和已有的worker。 private final BlockingQueue<Runnable>

什么是线程池?线程池的工作原理和使用线程池的好处

﹥>﹥吖頭↗ 提交于 2019-12-02 18:40:28
一个线程池管理了一组工作线程,同时它还包括了一个用于放置等待执行任务的任务队列(阻塞队列) 默认情况下,在创建了线程池后,线程池中的线程数为0.当任务提交给线程池之后的处理策略如下: 1:如果此时线程池中的数量小于corePoolSize(核心池的大小),即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务(也就是说每来一个任务,就要创建一个线程来执行任务) 2:如果此时线程池中的数量大于等于corePoolSize ,但是缓冲队列workQueue未满,那么任务被放入缓冲队列,则该任务会等待空闲线程将其取出去执行。 3:如果此时线程池中的数量大于等于corePoolSize,缓冲队列也满了,但是线程池中的数量小于maximumPoolSize(线程池最大线程数),此时就会建新的线程来处理被添加的任务。 4:如果此时线程池中的数量大于等于corePoolSize,缓冲队列满,线程池中的数量等于maximumPoolSize,那么通过RejectedExecutionHandler所指定的任务拒绝策略来处理此任务。 5:特别注意,在 corePoolSize 和 maximumPoolSize 之间的线程数会被自动释放。当线程池中线程数量大于 corePoolSize 时,如果某线程空闲时间超过 keepAliveTime,线程将被终止,直至线程池中的线程数目不大于

理解线程池的原理

浪子不回头ぞ 提交于 2019-12-02 18:36:42
读完本文你将了解: 什么是线程池 线程池的处理流程 保存待执行任务的阻塞队列 创建自己的线程池 JDK 提供的线程池及使用场景 newFixedThreadPool newSingleThreadExecutor newCachedThreadPool newScheduledThreadPool 两种提交任务的方法 execute submit 关闭线程池 如何合理地选择或者配置 总结 Thanks 什么是线程池 线程池的概念大家应该都很清楚,帮我们重复管理线程,避免创建大量的线程增加开销。 除了降低开销以外,线程池也可以提高响应速度,了解点 JVM 的同学可能知道,一个对象的创建大概需要经过以下几步: 检查对应的类是否已经被加载、解析和初始化 类加载后,为新生对象分配内存 将分配到的内存空间初始为 0 对对象进行关键信息的设置,比如对象的哈希码等 然后执行 init 方法初始化对象 创建一个对象的开销需要经过这么多步,也是需要时间的嘛,那可以复用已经创建好的线程的线程池,自然也在提高响应速度上做了贡献。 线程池的处理流程 创建线程池需要使用 ThreadPoolExecutor 类,它的构造函数参数如下: public ThreadPoolExecutor( int corePoolSize, //核心线程的数量 int maximumPoolSize, //最大线程数量