线程数

线程数究竟设多少合理

半城伤御伤魂 提交于 2019-12-04 04:30:44
一、需求缘起 Web-Server 通常有个配置, 最大工作线程数 ,后端服务一般也有个配置,工作线程池的 线程数量 ,这个线程数的配置不同的业务架构师有不同的经验值,有些业务设置为 CPU 核数的 2 倍,有些业务设置为 CPU 核数的 8 倍,有些业务设置为 CPU 核数的 32 倍。 “工作线程数”的设置依据是什么,到底设置为多少能够最大化CPU性能 ,是本文要讨论的问题。 二、一些共性认知 在进行进一步深入讨论之前,先以提问的方式就一些共性认知达成一致。 提问:工作线程数是不是设置的越大越好? 回答: 肯定不是的 1 )一来服务器 CPU 核数有限,同时并发的线程数是有限的, 1 核 CPU 设置 10000 个工作线程没有意义 2 )线程切换是有开销的,如果线程切换过于频繁,反而会使性能降低 提问:调用 sleep() 函数的时候,线程是否一直占用 CPU ? 回答: 不占用 ,等待时会把 CPU 让出来,给其他需要 CPU 资源的线程使用 不止调用 sleep() 函数,在进行一些阻塞调用,例如网络编程中的 阻塞 accept() 【等待客户端连接】和 阻塞 recv() 【等待下游回包】也不占用CPU资源 提问:如果 CPU 是单核,设置多线程有意义么,能提高并发性能么? 回答: 即使是单核,使用多线程也是有意义的 1 )多线程编码可以让我们的服务 / 代码更加清晰

多线程并发编程总结(三)

这一生的挚爱 提交于 2019-12-04 04:12:13
本文基于 https://github.com/h2pl/Java-Tutorial 的总结 Java 线程池 在线程池的使用过程中,我们是往线程池提交任务(task),提交的每个任务是实现了 Runnable 接口的。 如果线程数达到 corePoolSize,我们的每个任务会提交到等待队列中,等待线程池中的线程来取任务并执行。 阻塞队列,在执行任务之前用于保存任务的队列维护着等待执行的Runnable对象。 当所有的核心线程都在干活时,新添加的任务会被添加到这个队列中等待处理,如果队列满了,则新建非核心线程执行任务。 Executor 接口(只有提交任务的功能) ExecutorService 接口(线程池通用功能) public interface ExecutorService extends Executor { void shutdown(); List<Runnable> shutdownNow(); boolean isShutdown(); // 如果调用了 shutdown() 或 shutdownNow() 方法后,所有任务结束了,那么返回true // 这个方法必须在调用shutdown或shutdownNow方法之后调用才会返回true boolean isTerminated(); // 等待所有任务完成,并设置超时时间 // 我们这么理解,实际应用中是

用户态多线程的3种实现方式

不羁岁月 提交于 2019-12-04 01:45:17
用户态的线程概念和内核态的线程概念不同。有三种模式,分别是: (1).一对一 用户态一个线程对应内核态一个线程。用户态的线程并发执行,是真的并发执行。一个线程阻塞,不会影响其它线程。 缺点: a:许多系统限制内核线程数量,这就直接限制了用户态的线程数量。 b:许多系统中,内核线程间的调度花销大,导致用户线程的执行效率下降。 (2)多对一 一个内核线程可以用于生成多个用户态线程。 优点:线程间切换花销小,高效的上下文切换,速度因此快了。用户态的线程数几乎是无限制的。 缺点:一个用户态线程阻塞,对应的内核线程也会阻塞,那么此内核态衍生出来的用户态线程组都阻塞了。 特征:因为是共用一个内核线程,随着用户态线程数的增加,线程的性能不会有明显的增加。 (3)多对多 像交换机一样,多个用户态线程通过一个中转节点,对应上内核态的多个线程。 优点:一个用户态线程阻塞,不会使得其它线程阻塞。线程数没限制。在多处理器系统上,性能有一定提升(但比不上一对一的)。 来源: CSDN 作者: Norton-Linux内核研究 链接: https://blog.csdn.net/xzongyuan/article/details/20936533

并发与多线程

放肆的年华 提交于 2019-12-03 15:05:21
知识点汇总 一、死锁 1.1 竞争条件与临界区 1.2 死锁检测与防止 1.3 产生条件   互斥   请求并持有   非剥夺   循环等待 二、线程的状态与转换 NEW:创建 RUNNABLE:可运行 REDAY:就绪态 RUNNING:运行态 BLOCKED:获取锁失败进入BLOCKED状态,获取锁时进入REDAY态 TIME_WAITING:超时等待 WAITING:无超时等待 TERMINATED:结束 掌握5种状态即可(新建、就绪、运行、阻塞、死亡) 三、线程同步与互斥解决方法   1、CAS   2、synchronize   3、lock 3.1 CAS   CAS是乐观锁,轻量级锁,通过比较值是否被更改来判断。   缺点:可能会出现的ABA(上图右)的问题,不一定会影响结果,解决办法是提供额外的标志位或者时间戳(类似于mysql version字段)。 3.2 synchronize   方法同步:通过java的高级字节码指令ACC_SYNCCHRONIZED标志来实现。   代码块同步:通过java的两个高级字节码指令monitorenter和monitorexit来实现。   锁优化机制:   1、偏向锁:先使用偏向锁   2、轻量锁:获取偏向锁失败则升级为CAS轻量锁   3、自旋锁:获取轻量锁失败,则进行短暂的自旋   4、重量级锁

Python控制多进程与多线程并发数

蹲街弑〆低调 提交于 2019-12-03 14:19:36
Python控制多进程与多线程并发数 0x01 前言 本来写了脚本用于暴力破解密码,可是1秒钟尝试一个密码2220000个密码我的天,想用多线程可是只会一个for全开,难道开2220000个线程吗?只好学习控制线程数了,官方文档不好看,觉得结构不够清晰,网上找很多文章也都不很清晰,只有for全开线程,没有控制线程数的具体说明,最终终于根据多篇文章和官方文档算是搞明白基础的多线程怎么实现法了,怕长时间不用又忘记,找着麻烦就贴这了,跟我一样新手也可以参照参照。 先说进程和线程的区别: (1)地址空间:进程内的一个执行单元;进程至少有一个线程;它们共享进程的地址空间;而进程有自己独立的地址空间; (2)资源拥有:进程是资源分配和拥有的单位,同一个进程内的线程共享进程的资源 (3)线程是处理器调度的基本单位,但进程不是. (4)二者均可并发执行. 不能理解的话简单打比方就是一个进程就像一个程序一样,并发互不干扰。一个进程靠一个或多个线程执行处理,并发的线程是cpu在不停的来回切换执行,当然是快到你感觉不出的。 拿上面我遇到的困难来说吧,大量的数据需要执行相同的处理,一个操作中间可能会有一些等待时间,一个一个执行浪费大量时间,那么就同时执行吧,我们可以用两种并行办法: 进程 并行或者 线程 并行 各有优缺点,要看情况,不是绝对的,在此不讨论这个,这引出下面两种Python并行处理方法

线程池创建多少线程比较合理

白昼怎懂夜的黑 提交于 2019-12-03 13:59:31
在设置线程池线程个数的时候,经常会想到这个问题,是不是设置的线程数越多越好?理解这个问题之前我们要先清楚的知道我们为什么使用多线程。 为什么会使用多线程 使用多线程的主要目的我们应该都能回答的出来就是提高程序的性能,这个提高性能其实是指,降低延迟 指发送请求到接收到数据的时间,和 提搞吞吐量:单位时间能可以处理更多的请求。 将近延迟和提高吞吐量对应的方法有两种: 优化算法和机器的硬件性能发挥到极致。优化算法降低时间和空间复杂度,使的程序执行时间更短。硬件的性能发挥到极致,具体的指提高 I/O 和 cpu 的利用率,如何提高 I/O 和 cpu 的利用率的举例:如果单核系统中只有一个程序执行又有 IO 操作和 Cpu 计算的代码,当程序执行 IO 操作的时候,Cpu 其实是空闲的,反之 IO 是空闲的,如果这个时候用两个线程去跑这段代码,一个线程执行 IO 操作 ,一个线程执行 Cpu 计算 ,这时 IO 和 Cpu 的利用率是不是发挥了极致? 创建多少线程比较合适 经过上面的分析,我们知道创建多少线程能够将硬件的利用率达到最高才是最好的线程数。 我们从线程的应用场景来分析,由于 IO 操作比 Cpu 计算耗时要久的多的,如果我们一段程序有 IO 操作和 Cpu 计算,我们可以称之为 IO 密集型计算。程序中没有 IO 操作只有 Cpu 的话称之为 Cpu 密集型程序。 IO

tomcat的maxThreads、acceptCount(最大线程数、最大排队数)

狂风中的少年 提交于 2019-12-03 13:59:24
tomcat 的Connector配置如下 <</span>Connector port="8080" protocol="HTTP/1.1"connectionTimeout="20000"redirectPort="8443"maxThreads="800" acceptCount="1000"/> 其中最后两个参数意义如下: maxThreads :tomcat起动的最大线程数,即同时处理的任务个数,默认值为200 acceptCount :当tomcat起动的线程数达到最大时,接受排队的请求个数,默认值为100 这两个值如何起作用,请看下面三种情况 情况1:接受一个请求,此时tomcat起动的线程数没有到达maxThreads,tomcat会起动一个线程来处理此请求。 情况2:接受一个请求,此时tomcat起动的线程数已经到达maxThreads,tomcat会把此请求放入等待队列,等待空闲线程。 情况3:接受一个请求,此时tomcat起动的线程数已经到达maxThreads,等待队列中的请求个数也达到了acceptCount,此时tomcat会直接拒绝此次请求,返回connection refused maxThreads如何配置 一般的服务器操作都包括量方面:1计算(主要消耗cpu),2等待(io、数据库等) 第一种极端情况,如果我们的操作是纯粹的计算,

Tomcat实战-调优方案

折月煮酒 提交于 2019-12-03 13:13:55
作者 | 牛迁迁 来源 | https://blog.csdn.net/u010028869/article/details/51793821 Tomcat的默认配置,性能并不是最优的,我们可以通过优化tomcat以此来提高网站的并发能力。提高Tomcat的性能可以分为两个方向。 服务器资源 服务器所能提供CPU、内存、硬盘的性能对处理能力有决定性影响,所以说服务器性能牛B,Tomcat也不会太差。当然提高服务器的硬件配置,是需要大量RMB的支持的。所以不到万不得已不会采用这种方式,一般公司会采取下面这种通过优化配置,来提升Tomcat性能的方式。 优化配置 优化配置之前,我们需要配置一个tomcat管理员账户,来登录查看Tomcat控制台提高的各种参数。 在conf/ tomcat-users.xml下添加用户: <role rolename="manager"/> <role rolename="manager-gui"/> <role rolename="admin"/> <role rolename="admin-gui"/> <user username="tomcat" password="tomcat" roles="admin-gui,admin,manager-gui,manager"/> 启动tomcat,登录查看信息: http://127.0.0.1

java--线程池

别等时光非礼了梦想. 提交于 2019-12-03 06:32:22
转:https://www.cnblogs.com/zwwhnly/p/11777653.html 1. 为什么要使用多线程? 随着科技的进步,现在的电脑及服务器的处理器数量都比较多,以后可能会越来越多,比如我的工作电脑的处理器有8个,怎么查看呢? 计算机右键--属性--设备管理器,打开属性窗口,然后点击“设备管理器”,在“处理器”下可看到所有的处理器: 也可以通过以下Java代码获取到处理器的个数: System.out.println("CPU个数:" + Runtime.getRuntime().availableProcessors()); 运行结果如下所示: CPU个数:8 既然处理器的个数增加了,如果还使用传统的串行编程,就有点浪费资源了,因此,为了提高资源利用率,让各个处理器都忙碌起来,就需要引入并发编程,要引入并发编程,就引入了多线程。 可以说,使用多线程的最直接目的就是为了提高资源利用率,资源的利用率提高了,系统的吞吐率也就相应提高了。 2. 为什么要使用线程池? 在一定的范围内,增加线程可以提高应用程序的吞吐率,但线程并不是越多越好(因为线程的创建与销毁都需要很大的开销),如果超过了某个范围,不仅会降低应用程序的执行速度,严重的话,应用程序甚至会崩溃,以至于不得不重启应用程序。 为了避免这种问题,就需要对应用程序可以创建的线程数量进行限制

Java并发编程之线程池的使用

会有一股神秘感。 提交于 2019-12-03 04:40:14
1. 为什么要使用多线程? 随着科技的进步,现在的电脑及服务器的处理器数量都比较多,以后可能会越来越多,比如我的工作电脑的处理器有8个,怎么查看呢? 计算机右键--属性--设备管理器,打开属性窗口,然后点击“设备管理器”,在“处理器”下可看到所有的处理器: 也可以通过以下Java代码获取到处理器的个数: System.out.println("CPU个数:" + Runtime.getRuntime().availableProcessors()); 运行结果如下所示: CPU个数:8 既然处理器的个数增加了,如果还使用传统的串行编程,就有点浪费资源了,因此,为了提高资源利用率,让各个处理器都忙碌起来,就需要引入并发编程,要引入并发编程,就引入了多线程。 可以说,使用多线程的最直接目的就是为了提高资源利用率,资源的利用率提高了,系统的吞吐率也就相应提高了。 2. 为什么要使用线程池? 在一定的范围内,增加线程可以提高应用程序的吞吐率,但线程并不是越多越好(因为线程的创建与销毁都需要很大的开销),如果超过了某个范围,不仅会降低应用程序的执行速度,严重的话,应用程序甚至会崩溃,以至于不得不重启应用程序。 为了避免这种问题,就需要对应用程序可以创建的线程数量进行限制,确保在线程数量达到限制时,程序也不会耗尽资源,线程池就是为了解决这种问题而出现的。 线程池:管理一组工作线程的资源池。