• 浅聊Tomcat线程池


    正确的应用场景+合适的线程数量 = 快速运行速度

    Tomcat是目前比较流行的 Web 容器,接受请求之后都会转交给线程池处理,这样可以有效提高处理的能力与并发度

    经典老题: 创建线程池时应该给多大的核心线程数,最大线程数?

    抛开场景谈线程数都是耍流氓,

    场景的话 一般分为IO密集型与CPU密集型,也就是线程的大部分时间将用来计算还是等待IO

    一个原则就是,如果IO密集型,线程大部分时间用来等待IO结果,例如查数据库这种操作,线程等待IO结果CPU是空闲可以处理其他事情的,这样场景鼓励多创建线程并发执行

    如果是CPU密集型,线程大部分时间在执行CPU计算,一般创建这种 线程数 = CPU核心数+1即可 (+1是为了当线程运行后出问题,CPU有空闲可以额外处理一个线程)  这种场景就算创建再多的线程CPU也来不及执行,与线程数大致比例 1:1

    为什么Tomcat不用JDK原生线程池?

    想一想原生线程池的提交一个任务的运行过程

    总体的策略就是先让核心线程数的线程干活,多余的任务统统塞到阻塞队列,阻塞队列塞不下才再多创建线程来干活, 

    这种情况下当大量请求提交后,很可能大量的请求都会被阻塞在队列中 而线程还没有创建到最大线程数,导致用户请求处理很慢 用户体验很差,用户蚌埠住了、

    有个解决办法就是我直接把核心线程数set一个最大值,和最大线程数一样的值,这样不就先可着线程最大能力去处理,是在处理不过来再进队列吗。

    这样是可以做到,但是也就意味着创建的线程都是核心线程,那么多核心线程创建完了当没任务干的时候,那不是妥妥的浪费资源吗?

    Tomcat线程池是如何做的?

    简单的说

    1.新线程池继承JDK线程池接口,重写了execute()方法

    重写了execute()方法,当抛出拒绝策略了 再给一次机会,尝试往阻塞队列里插任务,尽最大努力的去执行任务 (意思是不抛弃不放弃,免得用户请求失败哭唧唧)

    2.新阻塞队列继承了LinkedBlockingQueue,重写了offer()方法

    重写了offer()方法,每次向队列插入任务,判断如果当前线程数小于最大线程数则插入失败。进而逼线程池创建新线程来处理任务 (意思你别想偷懒,把任务丢到队列就不管了)

    最后闲着也是闲着

    计算一下一台8核cpu的机器上,tomcat线程池应该配置多大? 每秒能处理多少请求?

    (假如机器不运行其他进程,没有其他线程会占用cpu资源)

    (假设每个请求查数据库IO时间大概是100ms)

    (假设每个请求cpu计算时间大概是10ms)

    如果单线程只会占用cpu10ms,剩下等待IO时间100ms,

    先按单核cpu来算,那也就是第一个请求会占用cpu10ms,然后就会去等IO。然后cpu处理第二个请求10ms,然后再处理第三个请求10ms,第四个,第五个....

    当处理完第11个的时候第一个请求的IO结束,请求完成 。当1秒钟结束时cpu处理了100个请求的计算,其中90个已经IO完毕返回结果。

    cpu同时可以处理十个请求,8核cpu同时可以处理80个请求,就会差不多支持900请求/s

  • 相关阅读:
    1006 Sign In and Sign Out
    1005 Spell It Right
    1004 Counting Leaves
    1003 Emergency
    PAT甲级练习题1001、1002
    翻转字符串.
    JavaScript实现弹幕效果
    SSI技术
    c#事务处理(sqlTransaction)
    Fiddler查看接口响应时间
  • 原文地址:https://www.cnblogs.com/ttaall/p/15220042.html
Copyright © 2020-2023  润新知