[第一篇]深入学习线程池之线程池简介及工作原理

一、什么是线程池?

通俗来讲,所谓的线程池就是一个线程的“集合”,在这个“集合”里,线程会被创造、回收,以及重复利用。就像一家餐厅一样,包括店长在内的员工就是线程,而这家餐厅就是“集合”,餐厅可以招聘(创造)、解雇员工(回收‘岗位’资源)、安排员工工作(重复利用)。

二、使用线程池的好处?

第一:降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
第二:提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。
第三:提高线程的可管理性。线程是稀缺资源,如果无限制地创建,不仅会消耗系统资源,
还会降低系统的稳定性,使用线程池可以进行统一分配、调优和监控。

还是上面的例子,如果一家餐厅只靠一个人来经营,在用餐高峰期的时候是忙不过来的,因为他既要帮客户点餐,又要把客户点好的餐送来,还要在客户吃完餐后收拾餐桌和处理掉盘碗碟筷等等。所以,做好的方式是组建一定的团队,比如,厨师、收银员、服务员等。

三、技术背景

在面向对象编程中,创建和销毁对象是非常费时间的,涉及到对内存资源和其他资源的占用和回收。在Java中,虚拟机将试图跟踪每个对象,以便在对象销毁后可以进行垃圾回收。所以提高服务程序效率的一个手段就是尽可能降低创建和销毁对象的次数,特别是一些非常耗资源的对象创建和销毁。

怎么重复利用已有对象进行服务是"池化资源"技术产生的原因。例如大家所熟悉的数据库连接池。

四、线程池工作原理

创建线程池,我们使用ThreadPoolExecutor,ThreadPoolExecutor构造器核心参数如下:

    public ThreadPoolExecutor(int corePoolSize,   #核心线程数
                              int maximumPoolSize,#最大线程数
                              long keepAliveTime, #达到最大线程数数时候,线程池的工作线程空闲后,保持存活的时间
                              TimeUnit unit,      #keepAliveTime单位
                              BlockingQueue<Runnable> workQueue,#阻塞队列
                              RejectedExecutionHandler handler  #饱和策略
    ) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), handler);
    }
线程池工作流程图

线程池任务执行流程:

  1. 当线程池小于corePoolSize时,新提交任务将创建一个新线程执行任务,即使此时线程池中存在空闲线程。
  2. 当线程池达到corePoolSize时,新提交任务将被放入workQueue中,等待线程池中任务调度执行
  3. 当workQueue已满,且maximumPoolSize > corePoolSize时,新提交任务会创建新线程执行任务
  4. 当提交任务数超过maximumPoolSize时,新提交任务由RejectedExecutionHandler处理
  5. 当线程池中超过corePoolSize线程,空闲时间达到keepAliveTime时,关闭空闲线程
  6. 当设置allowCoreThreadTimeOut(true)时,线程池中corePoolSize线程空闲时间达到keepAliveTime也将关闭

测试代码如下:

   final ThreadFactory threadFactory = new ThreadFactoryBuilder()
        .setNameFormat("Orders-%d")
        .setDaemon(true)
        .build();
    //线程池100个核心线程,最大200个线程,阻塞队列元素个数为1 饱和策略:直接丢弃
    final ThreadPoolExecutor executorService = new ThreadPoolExecutor(100, 200,
        10L, TimeUnit.SECONDS,
        new ArrayBlockingQueue<Runnable>(1), threadFactory,
        new ThreadPoolExecutor.DiscardPolicy());

    for (int i = 0; i < 120; i++) {
      executorService.submit(() -> {
        System.out.println("id=" + Thread.currentThread().getId() + ",threadName:" + Thread.currentThread().getName());
      });
    }

    executorService.shutdown();//关闭线程池,阻塞直到所有任务执行完毕
    System.out.println("the task is over!");

测试结果如下:

id=11,threadName:Orders-0
id=13,threadName:Orders-2
id=12,threadName:Orders-1
id=14,threadName:Orders-3
id=15,threadName:Orders-4
id=16,threadName:Orders-5
id=17,threadName:Orders-6
id=18,threadName:Orders-7
id=19,threadName:Orders-8
id=20,threadName:Orders-9
id=21,threadName:Orders-10
id=22,threadName:Orders-11
id=23,threadName:Orders-12
id=24,threadName:Orders-13
id=25,threadName:Orders-14
id=26,threadName:Orders-15
id=27,threadName:Orders-16
id=28,threadName:Orders-17
id=29,threadName:Orders-18
id=30,threadName:Orders-19
id=31,threadName:Orders-20
id=32,threadName:Orders-21
id=33,threadName:Orders-22
id=34,threadName:Orders-23
id=35,threadName:Orders-24
id=36,threadName:Orders-25
id=37,threadName:Orders-26
id=38,threadName:Orders-27
id=39,threadName:Orders-28
id=40,threadName:Orders-29
id=41,threadName:Orders-30
id=42,threadName:Orders-31
id=43,threadName:Orders-32
id=44,threadName:Orders-33
id=45,threadName:Orders-34
id=46,threadName:Orders-35
id=47,threadName:Orders-36
id=48,threadName:Orders-37
id=49,threadName:Orders-38
id=50,threadName:Orders-39
id=51,threadName:Orders-40
id=52,threadName:Orders-41
id=53,threadName:Orders-42
id=54,threadName:Orders-43
id=55,threadName:Orders-44
id=56,threadName:Orders-45
id=57,threadName:Orders-46
id=58,threadName:Orders-47
id=59,threadName:Orders-48
id=60,threadName:Orders-49
id=61,threadName:Orders-50
id=62,threadName:Orders-51
id=63,threadName:Orders-52
id=64,threadName:Orders-53
id=65,threadName:Orders-54
id=66,threadName:Orders-55
id=67,threadName:Orders-56
id=68,threadName:Orders-57
id=69,threadName:Orders-58
id=70,threadName:Orders-59
id=71,threadName:Orders-60
id=72,threadName:Orders-61
id=73,threadName:Orders-62
id=74,threadName:Orders-63
id=75,threadName:Orders-64
id=76,threadName:Orders-65
id=77,threadName:Orders-66
id=78,threadName:Orders-67
id=79,threadName:Orders-68
id=80,threadName:Orders-69
id=81,threadName:Orders-70
id=82,threadName:Orders-71
id=83,threadName:Orders-72
id=84,threadName:Orders-73
id=85,threadName:Orders-74
id=86,threadName:Orders-75
id=87,threadName:Orders-76
id=88,threadName:Orders-77
id=89,threadName:Orders-78
id=90,threadName:Orders-79
id=91,threadName:Orders-80
id=92,threadName:Orders-81
id=93,threadName:Orders-82
id=94,threadName:Orders-83
id=95,threadName:Orders-84
id=96,threadName:Orders-85
id=97,threadName:Orders-86
id=98,threadName:Orders-87
id=99,threadName:Orders-88
id=100,threadName:Orders-89
id=101,threadName:Orders-90
id=102,threadName:Orders-91
id=103,threadName:Orders-92
id=104,threadName:Orders-93
id=105,threadName:Orders-94
id=106,threadName:Orders-95
id=107,threadName:Orders-96
id=108,threadName:Orders-97
id=109,threadName:Orders-98
id=110,threadName:Orders-99
id=11,threadName:Orders-0
id=12,threadName:Orders-1
id=111,threadName:Orders-100
id=13,threadName:Orders-2
id=112,threadName:Orders-101
id=14,threadName:Orders-3
id=113,threadName:Orders-102
id=15,threadName:Orders-4
id=114,threadName:Orders-103
id=16,threadName:Orders-5
id=115,threadName:Orders-104
id=17,threadName:Orders-6
id=116,threadName:Orders-105
id=18,threadName:Orders-7
id=117,threadName:Orders-106
id=19,threadName:Orders-8
id=118,threadName:Orders-107
id=20,threadName:Orders-9
id=119,threadName:Orders-108
id=120,threadName:Orders-109
the task is over!
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,755评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,305评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,138评论 0 355
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,791评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,794评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,631评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,362评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,264评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,724评论 1 315
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,900评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,040评论 1 350
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,742评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,364评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,944评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,060评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,247评论 3 371
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,979评论 2 355

推荐阅读更多精彩内容