线程数

Java线程池详解及实例

喜夏-厌秋 提交于 2019-12-02 17:51:33
前言 多线程的异步执行方式,虽然能够最大限度发挥多核计算机的计算能力,但是如果不加控制,反而会对系统造成负担。线程本身也要占用内存空间,大量的线程会占用内存资源并且可能会导致Out of Memory。即便没有这样的情况,大量的线程回收也会给GC带来很大的压力。 为了避免重复的创建线程,线程池的出现可以让线程进行复用。通俗点讲,当有工作来,就会向线程池拿一个线程,当工作完成后,并不是直接关闭线程,而是将这个线程归还给线程池供其他任务使用。 接下来从总体到细致的方式,来共同探讨线程池。 总体的架构 来看Executor的框架图: 接口:Executor,CompletionService,ExecutorService,ScheduledExecutorService 抽象类:AbstractExecutorService 实现类:ExecutorCompletionService,ThreadPoolExecutor,ScheduledThreadPoolExecutor 从图中就可以看到主要的方法,本文主要讨论的是ThreadPoolExecutor 研读ThreadPoolExecutor 看一下该类的构造器: public ThreadPoolExecutor(int paramInt1, int paramInt2, long paramLong, TimeUnit

深度剖析线程池

夙愿已清 提交于 2019-12-02 14:26:52
之前在网上看一些面试题,每每看到线程池相关的都有种心虚的感觉,总感觉似懂非懂,禁不起敲打,也罢,好好写篇文章学习下线程池就。 类的结构 ExecutorService是我们常用的接口,继承了Ececutor,在Executor的基础上添加了很多功能。 ThreadPoolExecutor就是我们线程池的核心类了,可以用它的构造方法实现多种不同的线程池。 还有一种线程池ScheduledThreadPoolExecutor,适用于定时任务实现,碍于篇幅本文不再介绍 另外,还有个Executors类似于Collections,是个工具类,提供了直接生成一些常用线程池的方法,其实就是内部报了一个ThreadPoolExecuto,如下所示。 public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); } Executor void execute(Runnable command); Executor中只有这一个方法,可以看到是没有返回结果的。 ExecutorService public

Tomcat调优

断了今生、忘了曾经 提交于 2019-12-02 11:26:20
tomact调优:可以考 虑从内存,并发,缓存,安全,网络,系统等进行入手 内存优化 修改内存等 JVM相关配置 Linux下修改TOMCAT_HOME/bin/catalina.sh JAVA_OPTS="-server -XX:PermSize=512M -XX:MaxPermSize=1024m -Xms2048m -Xmx2048m windows下修改TOMCAT_HOME/bin/catalina.bat set JAVA_OPTS=-server -XX:PermSize=512M -XX:MaxPermSize=1024m -Xms2048m -Xmx2048m 参数介绍 -server:启用 JDK的 server 版本; -Xms:Java虚拟机初始化时堆的最小内存,一般与 Xmx配置为相同值,这样的好处是GC不必再为扩展内存空间而消耗性能; -Xmx:Java虚拟机可使用堆的最大内存; -XX:PermSize:Java虚拟机永久代大小; -XX:MaxPermSize:Java虚拟机永久代大小最大值; 验证 可以利用JDK自带的工具进行验证,这些工具都在JAVA_HOME/bin目录下: 1)jps:用来显示本地的java进程,以及进程号,进程启动的路径等。 2)jmap:观察运行中的JVM 物理内存的占用情况,包括Heap size , Perm

线程池线程数目的确定

雨燕双飞 提交于 2019-12-02 11:26:03
在上一篇文章 《java线程的创建(重点:线程池的使用,线程池不允许使用Executors创建)》 中有关线程池的配置中, public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) { ...... } 缓冲队列queue和异常处理策略handler已经说明,但还有两个重要的参数设置: 核心线程数corePoolSize,最大线程数maximumPoolSize 。所以线程数的确定也很重要,下面是我查阅资料和自己理解的结果 线程和哪些因素有关? 1. CPU 在最开始介绍多线程 《多线程的由浅及深》 时,介绍到 线程共享进程的上下文环境,为更细粒度的CPU时间段 。所以线程数的确定和CPU有关。至于CPU的核数和线程数的关系,可以查看这篇文章: CPU的核心数、线程数的关系和区别 。(多线程实际上是计算机多种资源的并行运用,跟CPU有几个核心是没什么关系的) 2. IO IO分为磁盘IO和网络IO。影响磁盘的关键因数是磁盘服务时间,即磁盘完成一个I/O请求所花费的时间,它由寻道时间

高并发之——线程池

假装没事ソ 提交于 2019-12-02 11:05:40
1.new Thread弊端 (1)每次new Thread新建对象,性能差 (2)线程缺乏统一管理,可能无限制的新建线程,相互竞争,有可能占用过多系统资源导致死机或OOM (3)缺少更多的功能,如更多执行、定期执行、线程中断 2.线程池的好处 (1)重用存在的线程,减少对象创建、消亡的开销,性能佳 (2)可以有效控制最大并发线程数,提高系统资源利用率,同时可以避免过多资源竞争,避免阻塞 (3)提供定时执行、定期执行、单线程、并发数控制等功能 线程池 - ThreadPoolExecutor ThreadPoolExecutor参数最多的构造方法如下: public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler rejectHandler) 接收如下参数进行初始化: (1)corePoolSize:核心线程数量 (2)maximumPoolSize:最大线程数 (3)workQueue:阻塞队列,存储等待执行的任务,很重要,会对线程池运行过程产生重大影响。

java 线程池那点事儿

时光毁灭记忆、已成空白 提交于 2019-12-02 05:54:39
1.为什么要用线程池 2.常见线程池以及参数 2.1 创建线程池 2.2 线程池参数 2.3 常见线程池 3.执行流程 4.健康检查 1.为什么要用线程池 线程池提供了一种任务的提交与任务的执行解偶的策略,并且有以下几种优势 提高资源利用率 通过复用自己的线程来降低创建线程和销毁线程的开销。 如果不用线程池而采用为每个任务都创建一个新线程的话会很浪费系统资源。因为创建线程和销毁线程都是耗系统资源的行为。除此之外还会由于线程过多而导致JVM出现OutOfMemory 提高响应速度 当新来一个任务时,如果有空闲线程存在可立即执行任务,中间节省了创建线程的过程 统一管理线程 如果不用线程池来管理,而是无限创建线程的话不仅消耗系统资源,而且还会导致系统不稳定。使用线程池可以进行统一分配,调优以及监控。 2.常见线程池以及参数 2.1 创建线程池 通过Executors的工厂方法来创建线程池,比如创建一个固定线程数的线程池 ExecutorService executorService = Executors.newFixedThreadPool(5); 通过ThreadPoolExecutor的构造函数来创建线程池 ThreadPoolExecutor pool = new ThreadPoolExecutor(int corePoolSize, int maxmumPoolSize,

java的单进程多线程模式

半腔热情 提交于 2019-12-02 03:49:46
java是单进程多线程模型,多线程依然可以充分利用多核(core)/多处理器(cpu) 单个cpu线程在同一时刻只能执行单一指令,也就是一个线程 单个线程同时只能在单个cpu线程中执行 Java中的所有线程在JVM进程中,CPU调度的是进程中的线程 Java多线程并不是由于cpu线程数为多个才称为多线程(单个核的单个cpu不使用超线程,仍然可以实现Java的多线程,只是所有的线程都跑在OS的单个线程里),当Java线程数大于cpu线程数,操作系统使用时间片轮转(RR)调度算法,频繁的进行上下文切换,以便并发执行其他线程 默认情况下,Java中每创建一个线程,操作系统会分配1M的栈空间 cpu执行Java程序,其根本是执行java代码编译后的操作系统可以识别的指令,cpu执行一条指令的时间是ns级别的(1.6G的cpu执行一条指令,大概需要0.6ns),而cpu上下文切换则需要2万个CPU时间周期 /proc/sys/kernel/thread-max 系统可以生成最大线程数量 /proc/sys/kernel/pid_max 增大,线程数量增大,pid_max有最高值,超过之后不再改变,而且32,64位也不一样 线程数量设置 经验值:服务器线程数*2+1 计算密集型的,则创建的线程数 = 处理器核心数 如果io操作比较耗时,则根据具体情况调整线程数,此时线程数 = n*处理器核心数

tomcat高并发优化的参数优化

↘锁芯ラ 提交于 2019-12-02 02:07:21
在Tomcat配置文件conf下面 server.xml 中的配置中和连接数相关的参数有: minProcessors:最小空闲连接线程数,用于提高系统处理性能,默认值为10 maxProcessors:最大连接线程数,即:并发处理的最大请求数,默认值为75 acceptCount:允许的最大连接数,应大于等于maxProcessors,默认值为100 enableLookups:是否反查域名,取值为:true或false。为了提高处理能力,应设置为false connectionTimeout:网络连接超时,单位:毫秒。设置为0表示永不超时,这样设置有隐患的。通常可设置为30000毫秒。 参数修改 默认的tomcat 参数: <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> 修改: <Connector port=“8080" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="600" minSpareThreads="100" maxSpareThreads="500" acceptCount="700" connectionTimeout="20000"

JVM和线程池

别来无恙 提交于 2019-12-01 22:00:31
本文链接:https://blog.csdn.net/liuwenliang_002/article/details/90074283 ———————————————— 版权声明:本文为CSDN博主「30以后的男人」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/liuwenliang_002/article/details/90074283 jvm结构原理,GC工作原理 Jvm结构: Jvm主要包括四个部分: 1、类加载器(ClassLoad) 在JVM启动时或者在类运行时将需要的class加载到JVM中。 类加载时间与过程: 类从被加载到虚拟机内存开始,在到卸载出内存为止,正式生命周期包括了:加载,验证,准备,解析,初始化,使用和卸载7个阶段。其中验证、准备、解析这个三个步骤被统称为连接(linking)。 其中,加载、验证、准备、初始化和卸载这五个阶段的顺序是确定的 ,类的加载过程必须按照这种顺序按部就班的“开始”(仅仅指的是开始,而非执行或者结束,因为这些阶段通常都是互相交叉的混合进行,通常会在一个阶段执行的过程中调用或者激活另一个阶段),而解析阶段则不一定(它在某些情况下可以在初始化阶段之后再开始,这是为了支持java语言的运行时绑定) 在以下几种情况下

十、自定义ThreadPoolExecutor线程池

大城市里の小女人 提交于 2019-12-01 20:27:01
自定义ThreadPoolExecutor线程池 自定义线程池需要遵循的规则 【1】线程池大小的设置 1、计算密集型: 顾名思义就是应用需要非常多的CPU计算资源,在多核CPU时代,我们要让每一个CPU核心都参与计算,将CPU的性能充分利用起来,这样才算是没有浪费服务器配置,如果在非常好的服务器配置上还运行着单线程程序那将是多么重大的浪费。对于计算密集型的应用,完全是靠CPU的核数来工作,所以为了让它的优势完全发挥出来,避免过多的线程上下文切换,比较理想方案是: ​ 线程数 = CPU核数+1,也可以设置成CPU核数*2,但还要看JDK的版本以及CPU配置(服务器的CPU有超线程)。 ​ 一般设置CPU * 2即可。 2、IO密集型 我们现在做的开发大部分都是WEB应用,涉及到大量的网络传输,不仅如此,与数据库,与缓存间的交互也涉及到IO,一旦发生IO,线程就会处于等待状态,当IO结束,数据准备好后,线程才会继续执行。因此从这里可以发现,对于IO密集型的应用,我们可以多设置一些线程池中线程的数量,这样就能让在等待IO的这段时间内,线程可以去做其它事,提高并发处理效率。那么这个线程池的数据量是不是可以随便设置呢?当然不是的,请一定要记得,线程上下文切换是有代价的。目前总结了一套公式,对于IO密集型应用: 线程数 = CPU核心数/(1-阻塞系数) 这个阻塞系数一般为0.8~0.9之间