@@ -465,14 +465,14 @@ static class Entry extends WeakReference<ThreadLocal<?>> {
465
465
466
466
### 4.1. 为什么要用线程池?
467
467
468
- > ** 池化技术相比大家已经屡见不鲜了 ,线程池、数据库连接池、Http 连接池等等都是对这个思想的应用。池化技术的思想主要是为了减少每次获取资源的消耗,提高对资源的利用率。**
468
+ > ** 池化技术想必大家已经屡见不鲜了 ,线程池、数据库连接池、Http 连接池等等都是对这个思想的应用。池化技术的思想主要是为了减少每次获取资源的消耗,提高对资源的利用率。**
469
469
470
470
** 线程池** 提供了一种限制和管理资源(包括执行一个任务)。 每个** 线程池** 还维护一些基本统计信息,例如已完成任务的数量。
471
471
472
472
这里借用《Java 并发编程的艺术》提到的来说一下** 使用线程池的好处** :
473
473
474
474
- ** 降低资源消耗** 。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
475
- - ** 提高响应速度** 。当任务到达时,任务可以不需要的等到线程创建就能立即执行 。
475
+ - ** 提高响应速度** 。当任务到达时,任务可以不需要等到线程创建就能立即执行 。
476
476
- ** 提高线程的可管理性** 。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。
477
477
478
478
### 4.2. 实现 Runnable 接口和 Callable 接口的区别
@@ -601,7 +601,7 @@ public ThreadPoolExecutor(int corePoolSize,
601
601
602
602
** ` ThreadPoolExecutor ` 3 个最重要的参数:**
603
603
604
- - ** ` corePoolSize ` :** 核心线程数线程数定义了最小可以同时运行的线程数量 。
604
+ - ** ` corePoolSize ` :** 核心线程数定义了最小可以同时运行的线程数量 。
605
605
- ** ` maximumPoolSize ` :** 当队列中存放的任务达到队列容量的时候,当前可以同时运行的线程数量变为最大线程数。
606
606
- ** ` workQueue ` :** 当新任务来的时候会先判断当前运行的线程数量是否达到核心线程数,如果达到的话,新任务就会被存放在队列中。
607
607
@@ -803,7 +803,7 @@ public void execute(Runnable command) {
803
803
804
804
![ 图解线程池实现原理] ( images/java线程池学习总结/图解线程池实现原理.png )
805
805
806
- 现在,让我们在回到 4.6 节我们写的 Demo, 现在应该是不是很容易就可以搞懂它的原理了呢 ?
806
+ 现在,让我们在回到 4.6 节我们写的 Demo, 现在是不是很容易就可以搞懂它的原理了呢 ?
807
807
808
808
没搞懂的话,也没关系,可以看看我的分析:
809
809
@@ -933,7 +933,7 @@ AQS 原理这部分参考了部分博客,在 5.2 节末尾放了链接。
933
933
934
934
** AQS 核心思想是,如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并且将共享资源设置为锁定状态。如果被请求的共享资源被占用,那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制,这个机制 AQS 是用 CLH 队列锁实现的,即将暂时获取不到锁的线程加入到队列中。**
935
935
936
- > CLH(Craig,Landin, and Hagersten)队列是一个虚拟的双向队列(虚拟的双向队列即不存在队列实例,仅存在结点之间的关联关系)。AQS 是将每条请求共享资源的线程封装成一个 CLH 锁队列的一个结点(Node)来实现锁的分配。
936
+ > CLH(Craig,Landin and Hagersten)队列是一个虚拟的双向队列(虚拟的双向队列即不存在队列实例,仅存在结点之间的关联关系)。AQS 是将每条请求共享资源的线程封装成一个 CLH 锁队列的一个结点(Node)来实现锁的分配。
937
937
938
938
看个 AQS(AbstractQueuedSynchronizer)原理图:
939
939
0 commit comments