通俗易懂的Java线程池技术

最近在给小伙伴说明线程池技术的时候,用到了一个例子,发现比较适合,在这记录一下。

很多书籍和文章都会说,如果请求很多的话,频繁的创建和销毁线程容易造成资源的消耗和浪费,降低系统的响应,这个时候,需要对线程进行的统一分配、监控、管理,线程池技术就派上用场了。

先看一下Java中关于线程池 ThreadPoolExecutor 的创建

 public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler)

分别对这几个参数做一个说明:

  • corePoolSize :核心线程数,线程池中可以长期存在的线程数量,即使没有任务提交到线程池,也不会被销毁。
  • maximumPoolSize :最大线程数,线程池中最多可以创建来执行任务的线程上限。
  • keepAliveTime :存活时间,超过 maximumPoolSize 数量外的线程的存活时间,超过这个时间没有执行任务时会被销毁。
  • TimeUnit : keepAliveTime 的单位。
  • workQueue : 任务队列,没有得到执行的任务,会放入这个队列中等待空闲的线程来执行它。
  • threadFactory : 线程工厂,定义创建新线程的方式,包括线程名称,线程组等。
  • handler :拒绝策略,当 workQueue 已满,并且 线程数量达到了maximumPoolSize,会对新提交的任务执行拒绝策略。

再来看看线程池的工作原理:

  • 如果线程池中的线程数量没超过corePoolSize,创建一个新线程来执行任务。
  • 如果线程池中的线程数量达到corePoolSize,将任务放入workQueue。
  • 如果workQueue已满,线程池中的线程数量没超过maximumPoolSize,创建新线程来执行任务。
  • 线程池中的线程执行完一个任务后,会从workQueue取任务执行。
  • 超过corePoolSize的线程如果空闲超过keepAliveTime没有执行任务,就要进行销毁。
  • 如果workQueue已满,且线程池中的线程数量达到maximumPoolSize,执行拒绝策略 handler。

- - - - - - - - - - - - - - 这是一个分割线 - - - - - - - - - - - - -

上边就是官网中对线程池参数的一些说明,这一个个参数看起来都什么玩意儿,说的是人话吗,好吧,那我们用生活中的例子来重新说明一下。

首先,为什么要是用线程池技术,为什么说创建和销毁线程会消耗资源

让我们想象一下,有一个旅游村(假设叫象牙村吧)住着一户人家,就叫 老王 吧(不是老王八),经常有来旅游的人来化个缘吃个饭,这时候,老王把桌子椅子摆上,让这个人坐好,然后根据这个人的需要把他要吃的饭做好,等这个人吃完饭走了之后,把桌子椅子收拾好。假设来吃饭的人不多的话还好,来一个人就临时摆个桌子椅子就行;但是如果来吃饭的人很多,每次都要先把椅子摆好,等一个人吃完,把桌椅收起来,再把桌椅搬出来给下一个人用,这样反反复复,很浪费搬桌子的时间。这个时候,老王想:来旅游人也挺多的,我干脆开个饭店得了。

线程池技术应运而生:

  • 线程就相当于吃饭的桌子,每张桌子要配备一个服务员
  • 饭店就相当于线程池

接着,线程池里的参数对应过来代表什么意思:

  • corePoolSize :饭店大厅的桌子数,能供多少人共同吃饭,就算没人来吃饭,这个桌子也不会收起来。
  • maximumPoolSize :最多桌子数,大厅坐不下了,饭店在院子里再摆新的桌子。
  • keepAliveTime :存活时间,院子里的桌子多长时间没人用了,就要收起来。
  • TimeUnit : keepAliveTime 的单位。
  • workQueue : 饭店大厅坐满了的话,就要先排队。
  • threadFactory : 生产桌子的方式,知道是哪个饭店第几桌。这个有什么用呢?如果不指定的话,假设老王开了个饭店,老李开了个饭店,他们都没有自己指定的桌子供货商,那就默认使用村子里生产的桌子,按顺序的话就是 象牙村1号桌象牙村2号桌,万一发生了意外,客人吃着吃着肚子不舒服,或者这一桌的客人喝大了打了起来,只知道是 象牙村X号桌 出了问题,不知道该找老王还是老李,但是如果他们有自己的供货商,桌子就变成了老王饭店1号桌老李饭店9号桌,出了问题,能够溯源。所以一般建议大家使用自己的线程工厂,按业务对线程进行命名。
  • handler :当排队的队伍排满了,院子里也坐满了人,就要对新来的人执行拒绝策略。

最后,看看怎么用这个例子来解释线程池的工作原理:

  • 有一个客人要来吃饭的时候,如果饭店大厅没有坐满,就在大厅摆上桌椅,让这个客人吃饭。
  • 如果大厅坐满了,新来的人就要在门口的椅子上坐着排队,等待轮到自己的顺序,这个椅子可以限制数量,比如只排50个人,也可以不限制。
  • 如果门口排队的椅子已经坐满了,说明今天来吃饭的人实在太多,老王就要看看还有没有多余的桌子,有的话,就在院子里把桌子摆上给新来的人吃饭。
  • 一旦某一桌的客人吃完走了之后,这张桌子服务员就会,就从门口排队的客人里让最靠前的进店吃饭。
  • 院子里的桌子如果一段时间没人吃饭,说明过了吃饭的高峰期,客人不那么多了,超过keepAliveTime的空闲,就要把桌子收起来,这个服务员也回去休息。
  • 如果门口排队的椅子已经坐满,店里的桌子也都用完,要执行相应的拒绝策略。有这么几种策略
    1. AbortPolicy :默认的,抛出一个异常。相当于用大喇叭喊了一下:“本店吃饭人数太多啦,大家别挤了”。
    2. DiscardPolicy :直接丢弃。相当于跟客人说,现在人太多,不接待新客户了。
    3. DiscardOldestPolicy :丢弃排队最久的任务。相当于让门口椅子上排第一个的人出去,意思是,你都排这么久了,看来你也不饿,那你就别吃了吧。
    4. CallerRunsPolicy :接待者执行,意思就是在门口迎宾的那个人,把自己坐的桌子让出来给客人吃饭,但在这个客人吃完之前,他就没法再接待新的客人了。

再补充一下关于停止线程池的2个方法,这两个方法都会拒绝新任务,相当于说本店打烊了,不接待新客户,它们之间的区别在于:

  • shutdown() :允许在关店之前已经来店里的客人把饭吃完。
  • shutdownNow() :不但不让正在排队的客人进店吃饭,还会尝试把在店里没吃完的客人赶出去。这个方法比较暴力
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,817评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,329评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,354评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,498评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,600评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,829评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,979评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,722评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,189评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,519评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,654评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,329评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,940评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,762评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,993评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,382评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,543评论 2 349

推荐阅读更多精彩内容