1
0
mirror of https://github.com/Snailclimb/JavaGuide synced 2025-08-01 16:28:03 +08:00

[docs update]redis、多线程部分问题答案进一步完善优化

This commit is contained in:
Guide 2025-04-11 07:23:35 +08:00
parent 7b22f0a166
commit ff77b0cabf
5 changed files with 29 additions and 16 deletions

View File

@ -36,10 +36,10 @@ Redis 没有外部依赖Linux 和 OS X 是 Redis 开发和测试最多的两
Redis 内部做了非常多的性能优化,比较重要的有下面 4 点:
1. Redis 基于内存,内存的访问速度比磁盘快很多;
2. Redis 基于 Reactor 模式设计开发了一套高效的事件处理模型,主要是单线程事件循环和 IO 多路复用Redis 线程模式后面会详细介绍到);
3. Redis 内置了多种优化过后的数据类型/结构实现,性能非常高;
4. Redis 通信协议实现简单且解析高效
1. **纯内存操作 (Memory-Based Storage)** 这是最主要的原因。Redis 数据读写操作都发生在内存中,访问速度是纳秒级别,而传统数据库频繁读写磁盘的速度是毫秒级别,两者相差数个数量级。
2. **高效的 I/O 模型 (I/O Multiplexing & Single-Threaded Event Loop)** Redis 使用单线程事件循环配合 I/O 多路复用技术,让单个线程可以同时处理多个网络连接上的 I/O 事件(如读写),避免了多线程模型中的上下文切换和锁竞争问题。虽然是单线程,但结合内存操作的高效性和 I/O 多路复用,使得 Redis 能轻松处理大量并发请求Redis 线程模型会在后文中详细介绍到)。
3. **优化的内部数据结构 (Optimized Data Structures)** Redis 提供多种数据类型(如 String, List, Hash, Set, Sorted Set 等),其内部实现采用高度优化的编码方式(如 ziplist, quicklist, skiplist, hashtable 等。Redis 会根据数据大小和类型动态选择最合适的内部编码,以在性能和空间效率之间取得最佳平衡。
4. **简洁高效的通信协议 (Simple Protocol - RESP)** Redis 使用的是自己设计的 RESP (REdis Serialization Protocol) 协议。这个协议实现简单、解析性能好,并且是二进制安全的。客户端和服务端之间通信的序列化/反序列化开销很小,有助于提升整体的交互速度
> 下面这张图片总结的挺不错的,分享一下,出自 [Why is Redis so fast?](https://twitter.com/alexxubyte/status/1498703822528544770)。

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

View File

@ -239,21 +239,23 @@ TTL 改造的地方有两处:
池化技术想必大家已经屡见不鲜了线程池、数据库连接池、HTTP 连接池等等都是对这个思想的应用。池化技术的思想主要是为了减少每次获取资源的消耗,提高对资源的利用率。
**线程池**提供了一种限制和管理资源(包括执行一个任务)的方式。 每个**线程池**还维护一些基本统计信息,例如已完成任务的数量。
线程池提供了一种限制和管理资源(包括执行一个任务)的方式。 每个线程池还维护一些基本统计信息,例如已完成任务的数量。使用线程池主要带来以下几个好处:
这里借用《Java 并发编程的艺术》提到的来说一下**使用线程池的好处**
- **降低资源消耗**。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
- **提高响应速度**。当任务到达时,任务可以不需要等到线程创建就能立即执行。
- **提高线程的可管理性**。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。
1. **降低资源消耗**:线程池里的线程是可以重复利用的。一旦线程完成了某个任务,它不会立即销毁,而是回到池子里等待下一个任务。这就避免了频繁创建和销毁线程带来的开销。
2. **提高响应速度**:因为线程池里通常会维护一定数量的核心线程(或者说“常驻工人”),任务来了之后,可以直接交给这些已经存在的、空闲的线程去执行,省去了创建线程的时间,任务能够更快地得到处理。
3. **提高线程的可管理性**:线程池允许我们统一管理池中的线程。我们可以配置线程池的大小(核心线程数、最大线程数)、任务队列的类型和大小、拒绝策略等。这样就能控制并发线程的总量,防止资源耗尽,保证系统的稳定性。同时,线程池通常也提供了监控接口,方便我们了解线程池的运行状态(比如有多少活跃线程、多少任务在排队等),便于调优。
### 如何创建线程池?
**方式一:通过`ThreadPoolExecutor`构造函数来创建(推荐)。**
在 Java 中,创建线程池主要有两种方式:
![通过构造方法实现](./images/java-thread-pool-summary/threadpoolexecutor构造函数.png)
**方式一:通过 `ThreadPoolExecutor` 构造函数直接创建 (推荐)**
**方式二:通过 `Executor` 框架的工具类 `Executors` 来创建。**
![](https://oss.javaguide.cn/github/javaguide/java/concurrent/threadpoolexecutor-construtors.png)
这是最推荐的方式,因为它允许开发者明确指定线程池的核心参数,对线程池的运行行为有更精细的控制,从而避免资源耗尽的风险。
**方式二:通过 `Executors` 工具类创建 (不推荐用于生产环境)**
`Executors`工具类提供的创建线程池的方法如下图所示:

View File

@ -162,11 +162,15 @@ public static class CallerRunsPolicy implements RejectedExecutionHandler {
### 线程池创建的两种方式
**方式一:通过`ThreadPoolExecutor`构造函数来创建(推荐)。**
在 Java 中,创建线程池主要有两种方式:
![通过构造方法实现](./images/java-thread-pool-summary/threadpoolexecutor构造函数.png)
**方式一:通过 `ThreadPoolExecutor` 构造函数直接创建 (推荐)**
**方式二:通过 `Executor` 框架的工具类 `Executors` 来创建。**
![](https://oss.javaguide.cn/github/javaguide/java/concurrent/threadpoolexecutor-construtors.png)
这是最推荐的方式,因为它允许开发者明确指定线程池的核心参数,对线程池的运行行为有更精细的控制,从而避免资源耗尽的风险。
**方式二:通过 `Executors` 工具类创建 (不推荐用于生产环境)**
`Executors`工具类提供的创建线程池的方法如下图所示:

View File

@ -1,3 +1,10 @@
---
title: Java 24 新特性概览
category: Java
tag:
- Java新特性
---
[JDK 24](https://openjdk.org/projects/jdk/24/) 是自 JDK 21 以来的第三个非长期支持版本,和 [JDK 22](https://javaguide.cn/java/new-features/java22-23.html)、[JDK 23](https://javaguide.cn/java/new-features/java22-23.html)一样。下一个长期支持版是 **JDK 25**,预计今年 9 月份发布。
JDK 24 带来的新特性还是蛮多的,一共 24 个。JDK 22 和 JDK 23 都只有 12 个JDK 24 的新特性相当于这两次的总和了。因此,这个版本还是非常有必要了解一下的。