线程数

监控 Java 线程池运行状态

[亡魂溺海] 提交于 2019-11-27 10:22:26
参考:https://blog.csdn.net/l18848956739/article/details/89363321 但在实际开发过程中,在线程池使用过程中可能会遇到各方面的故障,如线程池阻塞,无法提交新任务等。 如果你想监控某一个线程池的执行状态,线程池执行类 ThreadPoolExecutor 也给出了相关的 API, 能实时获取线程池的当前活动线程数、正在排队中的线程数、已经执行完成的线程数、总线程数等。 总线程数 = 排队线程数 + 活动线程数 + 执行完成的线程数。 线程池使用示例: private static ExecutorService es = new ThreadPoolExecutor(50, 100, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(100000)); public static void main(String[] args) throws Exception { for (int i = 0; i < 100000; i++) { es.execute(() -> { System.out.print(1); try { Thread.sleep(1000); } catch (InterruptedException e) { e

动态调整线程数的python爬虫代码分享

萝らか妹 提交于 2019-11-27 06:27:27
  这几天在忙一个爬虫程序,一直在改进他,从一开始的单线程,好几秒一张图片(网络不好),,,到现在每秒钟十几张图片,,, 四个小时586万条数据,,,简直不要太爽 先上图      最终写出来的程序,线程数已经可以动态调整了,贼暴力。。。峰值能稳定在50个线程,具体思路可以继续看   这里终于用到了操作系统的知识,就是生产者和消费者的模型。。。(参考源码忘记记录了,抱歉   先简单说一下目标网站的情况,目标网站是一个图片网站,有一个列表页,点进列表页之后,可以看到很多图片,这只爬虫的目的是收集这些图片链接(有了链接当然也能下载了...   简单分析之后发现,在列表页,会向后台请求一个json格式的数据文件,然后js动态的把里面的id组合成一个链接,最终组成如下样式的链接      http://www.xxxxxx.com/photo/json?page=1977   显而易见,page参数就是指定页数的,那么,这里就可以先生成一个列表,用for循环把所有列表页的url加进去,接下来只需要遍历这个链接列表就好了。    #首先构造产品队列 for i in range(1,11613): url_list.append("http://www.xxxxxx.com/photo/json?page="+str(i)); print('产生链接完成');   接下来,就是启动生产者线程

线程 - 线程池

霸气de小男生 提交于 2019-11-27 01:40:47
线程池实现原理 线程池介绍 多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力。 假设一个服务器完成一项任务所需时间为:T1 创建线程时间,T2 在线程中执行任务的时间,T3 销毁线程时间。 如果:T1 + T3 远大于 T2,则可以采用线程池,以提高服务器性能。 一个线程池包括以下四个基本组成部分: 线程池管理器(ThreadPool):用于创建并管理线程池,包括 创建线程池,销毁线程池,添加新任务; 工作线程(PoolWorker):线程池中线程,在没有任务时处于等待状态,可以循环的执行任务; 任务接口(Task):每个任务必须实现的接口,以供工作线程调度任务的执行,它主要规定了任务的入口,任务执行完后的收尾工作,任务的执行状态等; 任务队列(taskQueue):用于存放没有处理的任务。提供一种缓冲机制。 Java 并发编程包 ThreadPoolExecutor corePoolSize 线程池中保留的线程数量。 在创建了线程池后,默认情况下,线程池中并没有任何线程,而是等待有任务到来才创建线程去执行任务,除非调用了prestartAllCoreThreads()或者prestartCoreThread()方法,从这2个方法的名字就可以看出,是预创建线程的意思

线程池全面解析

邮差的信 提交于 2019-11-26 23:46:33
什么是线程池? 很简单,简单看名字就知道是装有线程的池子,我们可以把要执行的多线程交给线程池来处理,和连接池的概念一样,通过维护一定数量的线程池来达到多个线程的复用。 线程池的好处 我们知道不用线程池的话,每个线程都要通过new Thread(xxRunnable).start()的方式来创建并运行一个线程,线程少的话这不会是问题,而真实环境可能会开启多个线程让系统和程序达到最佳效率,当线程数达到一定数量就会耗尽系统的CPU和内存资源,也会造成GC频繁收集和停顿,因为每次创建和销毁一个线程都是要消耗系统资源的,如果为每个任务都创建线程这无疑是一个很大的性能瓶颈。所以,线程池中的线程复用极大节省了系统资源,当线程一段时间不再有任务处理时它也会自动销毁,而不会长驻内存。 线程池核心类 在java.util.concurrent包中我们能找到线程池的定义,其中ThreadPoolExecutor是我们线程池核心类,首先看看线程池类的主要参数有哪些。 corePoolSize:线程池的核心大小,也可以理解为最小的线程池大小。 maximumPoolSize:最大线程池大小。 keepAliveTime:空余线程存活时间,指的是超过corePoolSize的空余线程达到多长时间才进行销毁。 unit:销毁时间单位。 workQueue:存储等待执行线程的工作队列。 threadFactory

并发数据结构 : SpinWait

纵然是瞬间 提交于 2019-11-26 21:44:45
老实说,没有哪个开发人员愿意在其编码时还要考虑线程同步。更糟糕的情况是,编写线程同步代码一点也不好玩。稍一不慎,就会导致共享资源状态不一致,从而引发程序未预期行为。此外,当我们添加线程同步代码时还会导致程序运行变慢,损害性能和可伸缩性。从这点上来看,线程同步简直一无是处。可惜,这也是现实生活中必要的一部分。尤其在多核CPU成为主流的今天。 考虑下这种情况:只有一个线程试图访问某个资源。在此种状况下,那些线程同步代码纯粹是额外开销。那么如何保护性能呢? 首先, 不要让线程从用户模式转到内核模式。 在Windows上,这是个非常昂贵的操作。比如大家熟知的Critical Section(在.NET上我们叫它Monitor)在等待持有锁时,便在用户模式先旋转等待一段时间,实在不行才转入内核模式。 其次,当线程进入等待状态时,它便停止运行。很显然,停止运行的线程还有啥性能可言。所幸的是,假如线程进入内核模式,它也就只能进入等待状态。所以,如果你遵守第一条规则(避免进入内核),那么第二条规则(不要让线程进入等待状态)将会自动遵守。我们应当 让线程大多数时间在运行而不是在等待 。 最后, 尽可能用尽量少的线程来完成任务 。最理想的情况是,从不让存在的线程数多于你的计算机上的CPU个数。因此,当你的机器只有四个CPU的时候,最好也不要超过四个线程的数量。为什么?因为当超过四个线程的时候

线程池学习总结

徘徊边缘 提交于 2019-11-26 20:28:04
一、为什么要使用线程池? 一般我们使用多线程,都是创建一个线程去执行任务。在执行完后,自动销毁线程。这样看上去没有问题,但是仔细想想。如果在并发的线程数量很多的时候,每个线程执行完一段任务就结束了,这样频繁的创建线程是会大大降低服务性能和占用大量内存资源并且可能会Out Of Memory。同时大量线程回收也会给GC带来很大的压力。 这时,使用线程池来管理线程的创建和销毁就十分有必要了。简单点说,线程池就像一个加工厂,而线程池里的线程就是加工厂的员工了。当有活来了,就会从加工厂中找一个员工分配他来完成这个工作,如果做完了也不会辞退它,而是让其等待下一个任务。 二、线程池Executor总体设计 今天我们重点讲java.uitl.concurrent.ThreadPoolExecutor类,所以我们从这个类出发,去了解线程池。 总体设计架构: 本章节,我们暂时只关注下面这一条设计线就行了。 ThreadPoolExecutor(实体类)---------->AbstractExecutorService(抽象类)------------> ExecutorService(接口)------------>Executor(接口) 1.部分源码分析以及解释 public class ThreadPoolExecutor extends AbstractExecutorService {

系统负载能力浅析

六月ゝ 毕业季﹏ 提交于 2019-11-26 20:05:36
系统负载能力浅析 —本文于2015.12.23号最新更新— 互联网时代,高并发是一个老生常谈的话提。无论对于一个web站点还是app应用,高峰时能承载的并发请求都是衡量一个系统性能的关键标志。像阿里双十一顶住了上亿的峰值请求、订单也确实体现了阿里的技术水平(当然有钱也是一个原因)。 那么,何为系统负载能力?怎么衡量?相关因素有哪些?又如何优化呢? 一. 衡量指标 用什么来衡量一个系统的负载能力呢?有一个概念叫做每秒请求数(Requests per second),指的是每秒能够成功处理请求的数目。比如说,你可以配置tomcat服务器的maxConnection为无限大,但是受限于服务器系统或者硬件限制,很多请求是不会在一定的时间内得到响应的,这并不作为一个成功的请求,其中成功得到响应的请求数即为每秒请求数,反应出系统的负载能力。 通常的,对于一个系统,增加并发用户数量时每秒请求数量也会增加。然而,我们最终会达到这样一个点,此时并发用户数量开始“压倒”服务器。如果继续增加并发用户数量,每秒请求数量开始下降,而反应时间则会增加。这个并发用户数量开始“压倒”服务器的临界点非常重要,此时的并发用户数量可以认为是当前系统的最大负载能力。 二. 相关因素 一般的,和系统并发访问量相关的几个因素如下: 带宽 硬件配置 系统配置 应用服务器配置 程序逻辑 系统架构 其中

Java 四种常见线程池解析

て烟熏妆下的殇ゞ 提交于 2019-11-26 18:02:15
目录 四种常见线程池 线程池工作流程 ThreadPoolExecutor ThreadPoolExecutor的重要属性 饱和策略 FixedThreadPool ChachedThreadPool SingleThreadExecutor ScheduledThreadPool 四种常见线程池   线程池用于管理线程的创建与销毁,避免无用线程造成资源浪费,当需要创建多个线程时,我们往往需要一个管理者来管理这些线程,这也就引入了线程池的概念.Android中有四种较为常见的线程池也是我们使用最广泛的线程池,FixedThreadPool(固定线程数的线程池),ChachedThreadPool(缓存型线程池),SingleThreadExecutor(单线程线程池),ScheduledThreadPool(周期性调度线程池).这几种线程池本质都是通过ThreadPoolExecutor来创建的.当然在使用中我们只需要通过Executors就能快速创建这几类线程池,但是我们需要理解其创建的具体流程. 线程池工作流程 ThreadPoolExecutor   这四种常见线程池创建的本质都是通过ThreadPoolExecutor来创建的,只是传入的参数不同就生成了不同的线程池,所以我们需要学习ThreadPoolExecutor的构造方法,这样我们就可以创建出符合我们需求的线程池了.

Tomcat使用线程池配置高并发连接

陌路散爱 提交于 2019-11-26 12:12:38
1:配置executor属性 打开/conf/server.xml文件,在Connector之前配置一个线程池: <Executor name="tomcatThreadPool" namePrefix="tomcatThreadPool-" maxThreads="1000" maxIdleTime="300000" minSpareThreads="200"/> 重要参数说明: name :共享线程池的名字。这是Connector为了共享线程池要引用的名字,该名字必须唯一。默认值:None; namePrefix :在JVM上,每个运行线程都可以有一个name 字符串。这一属性为线程池中每个线程的name字符串设置了一个前缀,Tomcat将把线程号追加到这一前缀的后面。默认值:tomcat-exec-; maxThreads :该线程池可以容纳的最大线程数。默认值:200; maxIdleTime :在Tomcat关闭一个空闲线程之前,允许空闲线程持续的时间(以毫秒为单位)。只有当前活跃的线程数大于minSpareThread的值,才会关闭空闲线程。默认值:60000(一分钟)。 minSpareThreads :Tomcat应该始终打开的最小不活跃线程数。默认值:25。 2:配置Connector <Connector executor="tomcatThreadPool"

C#异步编程的实现方式(3)&mdash;&mdash;ThreadPool线程池

大兔子大兔子 提交于 2019-11-26 11:04:57
在需要创建的线程很多,且都是比较小的线程的情况下,可以使用线程池(ThreadPool类)。ThreadPool是一个静态方法,提供了对一个线程集合的操作,它会在线程数不足时增加线程,空闲线程数过多时释放资源。 1、ThreadPool简单应用 调用ThreadPool.QueueUserWorkItem()方法,传递一个WaitCallBack委托类型的方法,并把这个方分配给线程池中的线程。线程池是自动运行的,如果线程池还没有运行,就会创建一个线程池,并启动第一个线程。如果线程池己经在运行,且有一个空闲线程来完成该任务,就把该作业传递给这个线程。 下面这个方法是一个符合WaitCallBack委托的方法: 1: static void WaitCallBackMethod( object param) 2: { 3: for ( int i = 0; i < 5; i++) 4: { 5: Console.WriteLine(String.Format( "Thread {0} is running" , param)); 6: Thread.Sleep(1000); 7: } 8: } 然后在主线程里给线程池添加方法: 1: static void Main( string [] args) 2: { 3: for ( int i = 1; i <= 3; i++) 4: {