mirror of
https://github.com/Snailclimb/JavaGuide
synced 2025-08-01 16:28:03 +08:00
Compare commits
5 Commits
0dca2672ed
...
a7c89a8702
Author | SHA1 | Date | |
---|---|---|---|
|
a7c89a8702 | ||
|
bce4d1a504 | ||
|
2c20c6fcc4 | ||
|
5c25afb8da | ||
|
64cbe0833c |
@ -272,7 +272,7 @@ void afterNodeAccess(Node < K, V > e) { // move node to last
|
|||||||
if (b == null)
|
if (b == null)
|
||||||
head = a;
|
head = a;
|
||||||
else
|
else
|
||||||
//如果后继节点不为空,则让前驱节点指向后继节点
|
//如果前驱节点不为空,则让前驱节点指向后继节点
|
||||||
b.after = a;
|
b.after = a;
|
||||||
|
|
||||||
//如果后继节点不为空,则让后继节点指向前驱节点
|
//如果后继节点不为空,则让后继节点指向前驱节点
|
||||||
@ -372,10 +372,10 @@ void afterNodeRemoval(Node<K,V> e) { // unlink
|
|||||||
|
|
||||||
从源码可以看出, `afterNodeRemoval` 方法的整体操作就是让当前节点 p 和前驱节点、后继节点断开联系,等待 gc 回收,整体步骤为:
|
从源码可以看出, `afterNodeRemoval` 方法的整体操作就是让当前节点 p 和前驱节点、后继节点断开联系,等待 gc 回收,整体步骤为:
|
||||||
|
|
||||||
1. 获取当前节点 p、以及 e 的前驱节点 b 和后继节点 a。
|
1. 获取当前节点 p、以及 p 的前驱节点 b 和后继节点 a。
|
||||||
2. 让当前节点 p 和其前驱、后继节点断开联系。
|
2. 让当前节点 p 和其前驱、后继节点断开联系。
|
||||||
3. 尝试让前驱节点 b 指向后继节点 a,若 b 为空则说明当前节点 p 在链表首部,我们直接将 head 指向后继节点 a 即可。
|
3. 尝试让前驱节点 b 指向后继节点 a,若 b 为空则说明当前节点 p 在链表首部,我们直接将 head 指向后继节点 a 即可。
|
||||||
4. 尝试让后继节点 a 指向前驱节点 b,若 a 为空则说明当前节点 p 在链表末端,所以直接让 tail 指针指向前驱节点 a 即可。
|
4. 尝试让后继节点 a 指向前驱节点 b,若 a 为空则说明当前节点 p 在链表末端,所以直接让 tail 指针指向前驱节点 b 即可。
|
||||||
|
|
||||||
可以结合这张图理解,展示了 key 为 13 的元素被删除,也就是从链表中移除了这个元素。
|
可以结合这张图理解,展示了 key 为 13 的元素被删除,也就是从链表中移除了这个元素。
|
||||||
|
|
||||||
|
@ -13,9 +13,9 @@ tag:
|
|||||||
|
|
||||||
`Executors` 返回线程池对象的弊端如下(后文会详细介绍到):
|
`Executors` 返回线程池对象的弊端如下(后文会详细介绍到):
|
||||||
|
|
||||||
- **`FixedThreadPool` 和 `SingleThreadExecutor`**:使用的是无界的 `LinkedBlockingQueue`,任务队列最大长度为 `Integer.MAX_VALUE`,可能堆积大量的请求,从而导致 OOM。
|
- **`FixedThreadPool` 和 `SingleThreadExecutor`**:使用的是有界阻塞队列 `LinkedBlockingQueue`,任务队列的默认长度和最大长度为 `Integer.MAX_VALUE`,可能堆积大量的请求,从而导致 OOM。
|
||||||
- **`CachedThreadPool`**:使用的是同步队列 `SynchronousQueue`, 允许创建的线程数量为 `Integer.MAX_VALUE` ,可能会创建大量线程,从而导致 OOM。
|
- **`CachedThreadPool`**:使用的是同步队列 `SynchronousQueue`,允许创建的线程数量为 `Integer.MAX_VALUE` ,可能会创建大量线程,从而导致 OOM。
|
||||||
- **`ScheduledThreadPool` 和 `SingleThreadScheduledExecutor`** : 使用的无界的延迟阻塞队列`DelayedWorkQueue`,任务队列最大长度为 `Integer.MAX_VALUE`,可能堆积大量的请求,从而导致 OOM。
|
- **`ScheduledThreadPool` 和 `SingleThreadScheduledExecutor`** : 使用的无界的延迟阻塞队列`DelayedWorkQueue`,任务队列最大长度为 `Integer.MAX_VALUE`,可能堆积大量的请求,从而导致 OOM。
|
||||||
|
|
||||||
说白了就是:**使用有界队列,控制线程创建数量。**
|
说白了就是:**使用有界队列,控制线程创建数量。**
|
||||||
|
|
||||||
@ -227,7 +227,7 @@ try {
|
|||||||
|
|
||||||
线程池本身的目的是为了提高任务执行效率,避免因频繁创建和销毁线程而带来的性能开销。如果将耗时任务提交到线程池中执行,可能会导致线程池中的线程被长时间占用,无法及时响应其他任务,甚至会导致线程池崩溃或者程序假死。
|
线程池本身的目的是为了提高任务执行效率,避免因频繁创建和销毁线程而带来的性能开销。如果将耗时任务提交到线程池中执行,可能会导致线程池中的线程被长时间占用,无法及时响应其他任务,甚至会导致线程池崩溃或者程序假死。
|
||||||
|
|
||||||
因此,在使用线程池时,我们应该尽量避免将耗时任务提交到线程池中执行。对于一些比较耗时的操作,如网络请求、文件读写等,可以采用异步操作的方式来处理,以避免阻塞线程池中的线程。
|
因此,在使用线程池时,我们应该尽量避免将耗时任务提交到线程池中执行。对于一些比较耗时的操作,如网络请求、文件读写等,可以采用 `CompletableFuture` 等其他异步操作的方式来处理,以避免阻塞线程池中的线程。
|
||||||
|
|
||||||
## 8、线程池使用的一些小坑
|
## 8、线程池使用的一些小坑
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user