锁相关

​1. 什么是可重入锁?Java 中如何实现?​​
​答​:
可重入锁允许一个线程多次获取同一把锁(即递归调用时无需重新竞争锁)。

  • ​关键点​:防止死锁,避免线程因重复请求已持有的锁而阻塞。
  • ​Java 实现​:
  • synchronized:隐式支持可重入。
    public synchronized void methodA() {
    methodB(); // 可重入
    }
    public synchronized void methodB() {}
  • ReentrantLock:显式锁,通过计数器实现可重入。
    ReentrantLock lock = new ReentrantLock();
    public void method() {
    lock.lock();
    try {
    // 递归调用或其他同步代码
    } finally {
    lock.unlock();
    }
    }
    ​2. ReentrantLock 与 synchronized 的区别?​​
    特性​​synchronized​​ReentrantLock​​实现方式​JVM 关键字,自动管理锁JDK 类,需手动加锁/解锁​锁获取灵活性​不支持中断或超时支持tryLock()、lockInterruptibly()​公平性​非公平锁可选公平/非公平模式(构造函数指定)​条件变量​仅通过wait()/notify()关联一个条件支持多个Condition对象​锁释放​自动释放(退出同步块或异常)必须在finally中手动释放

​3. 什么是读写锁(ReadWriteLock)?​​
​答​:
读写锁分离读操作(共享)和写操作(独占),提升并发性能。

  • ​规则​:
  • 读锁:允许多线程同时读,但排斥写锁。
  • 写锁:独占锁,排斥其他所有读写锁。
  • ​适用场景​:读多写少(如缓存)。
  • ​Java 实现​:ReentrantReadWriteLock
    ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
    public void readData() {
    rwLock.readLock().lock();
    try {
    // 读操作
    } finally {
    rwLock.readLock().unlock();
    }
    }
    public void writeData() {
    rwLock.writeLock().lock();
    try {
    // 写操作
    } finally {
    rwLock.writeLock().unlock();
    }
    }
    ​4. 死锁产生的条件?如何避免?​​
    ​死锁条件​:
    1.​互斥​:资源独占。
    2.​持有且等待​:线程持有资源并等待其他资源。
    3.​不可抢占​:资源只能由持有线程释放。
    4.​循环等待​:多个线程形成资源请求闭环。
    ​避免方法​:
  • ​破坏循环等待​:按固定顺序获取锁(如按锁对象的哈希值排序)。
    public void transfer(Account a, Account b, int amount) {
    Object firstLock = a.hashCode() < b.hashCode() ? a : b;
    Object secondLock = firstLock == a ? b : a;
    synchronized (firstLock) {
    synchronized (secondLock) {
    // 转账操作
    }
    }
    }
  • ​超时机制​:使用 tryLock() 设置超时时间。
    if (lock1.tryLock(1, TimeUnit.SECONDS)) {
    try {
    if (lock2.tryLock(1, TimeUnit.SECONDS)) {
    try { /* … */ } finally { lock2.unlock(); }
    }
    } finally { lock1.unlock(); }
    }
  • ​银行家算法​:动态检查资源分配是否安全(实际开发较少用)。
    ​5. 乐观锁与悲观锁的区别?​​
    类型​​原理​​实现​​适用场景​​悲观锁​假设会发生冲突,先加锁再操作synchronized、ReentrantLock写多读少​乐观锁​假设无冲突,更新时检查版本号CAS 操作(如AtomicInteger)、StampedLock读多写少

​CAS 示例​:
AtomicInteger count = new AtomicInteger(0);
public void increment() {
int oldVal, newVal;
do {
oldVal = count.get();
newVal = oldVal + 1;
} while (!count.compareAndSet(oldVal, newVal)); // CAS 更新
}
​6. synchronized 锁升级过程?​​
1.​无锁​:初始状态。
2.​偏向锁​:锁被同一线程多次访问时,记录线程 ID(避免 CAS 操作)。
3.​轻量级锁​:当多线程竞争时,通过 CAS 自旋尝试获取锁(减少阻塞)。
4.​重量级锁​:自旋超过阈值后,转为操作系统级互斥锁(线程阻塞)。

  • ​目的​:平衡性能与开销,减少直接使用重量级锁的成本。
    ​7. volatile 能否替代锁?​​
    ​答​:​不能完全替代。

  • volatile 特性​:

  • 保证可见性:修改后立即刷新到主内存。

  • 禁止指令重排序(内存屏障)。

  • ​不足​:

  • 不保证原子性(如 i++ 需配合锁或原子类)。

  • 无法实现互斥访问(如临界区保护)。
    ​适用场景​:

  • 状态标记(如 boolean flag = true)。

  • 单次读写操作(如 long、double 的 64 位写入)。
    ​8. 什么是自旋锁?​​
    ​答​:线程在获取锁失败时,不立即阻塞而是循环(自旋)重试,避免上下文切换开销。

  • ​实现​:
    public class SpinLock {
    private AtomicReference owner = new AtomicReference<>();

    public void lock() {
    Thread t = Thread.currentThread();
    while (!owner.compareAndSet(null, t)) {
    // 自旋等待
    }
    }
    public void unlock() {
    owner.set(null);
    }
    }

  • ​适用场景​:锁持有时间短、线程数少。

  • ​缺点​:长时间自旋浪费 CPU(JDK 的自旋锁有自适应策略)。
    ​9. StampedLock 是什么?​​
    ​答​:Java 8 引入的高性能读写锁,支持三种模式:
    1.​写锁​:独占锁(类似 ReentrantReadWriteLock 的写锁)。
    2.​悲观读锁​:共享锁(类似读锁)。
    3.​乐观读​:无锁操作,需验证是否有写发生。
    StampedLock sl = new StampedLock();

// 乐观读
long stamp = sl.tryOptimisticRead();
if (!sl.validate(stamp)) { // 检查期间是否有写操作
stamp = sl.readLock(); // 转为悲观读
try { /* … */ } finally { sl.unlockRead(stamp); }
}

  • ​优势​:乐观读避免锁开销,提升读性能。
    ​10. Condition 接口的作用?​​
    ​答​:配合 ReentrantLock 实现线程等待/唤醒机制,可替代 Object.wait()/notify()。
  • ​优势​:支持多个等待队列(如生产者-消费者模型)。
    java运行复制ReentrantLock lock = new ReentrantLock();
    Condition notFull = lock.newCondition(); // 队列未满条件
    Condition notEmpty = lock.newCondition(); // 队列非空条件

// 生产者
public void put(Object item) {
lock.lock();
try {
while (queue.isFull()) notFull.await(); // 等待未满
queue.add(item);
notEmpty.signal(); // 唤醒消费者
} finally { lock.unlock(); }
}

// 消费者
public Object take() {
lock.lock();
try {
while (queue.isEmpty()) notEmpty.await(); // 等待非空
notFull.signal(); // 唤醒生产者
return queue.remove();
} finally { lock.unlock(); }
}
​11. 锁消除(Lock Elision)和锁粗化(Lock Coarsening)是什么?​​

  • ​锁消除​:JIT 编译器移除不必要的锁(如局部变量锁)。
    public String concat(String s1, String s2) {
    StringBuffer sb = new StringBuffer(); // 局部变量,线程安全
    sb.append(s1).append(s2);
    return sb.toString();
    }
    // JIT 可能移除 StringBuffer 的同步操作
  • ​锁粗化​:合并多次加锁/解锁操作为一次(减少开销)。
    synchronized (obj) { /* 操作1 / }
    synchronized (obj) { /
    操作2 / }
    // 优化后 =>
    synchronized (obj) { /
    操作1+操作2 */ }
    ​12. 如何检测死锁?​​
    1.​命令行工具​:
  • jstack :查看线程堆栈,标记死锁信息。
  • jconsole:图形化检测死锁。
    2.​代码检测​:
    ThreadMXBean bean = ManagementFactory.getThreadMXBean();
    long[] threadIds = bean.findDeadlockedThreads();
    if (threadIds != null) {
    // 处理死锁
    }
    总结
  • ​基础锁​:synchronized(隐式)、ReentrantLock(显式)。
  • ​高级锁​:ReadWriteLock、StampedLock、Condition。
  • ​锁优化​:锁升级、消除、粗化。
  • ​避免死锁​:顺序加锁、超时机制。
  • ​工具​:乐观锁(CAS)、原子类、并发工具包(java.util.concurrent)。

synchronized和lock
synchronized vs Lock(以ReentrantLock为例)详解
​1. 实现机制​
特性​​synchronized​​Lock(ReentrantLock)​​​实现级别​JVM 内置关键字(字节码指令monitorenter/monitorexit)JDK API(Java 类实现)​锁状态保存​锁状态存储在对象头中(Mark Word)AQS(AbstractQueuedSynchronizer)维护锁状态

​2. 使用方式​
// ========== synchronized ==========
// 1. 方法级锁
public synchronized void syncMethod() { // }

// 2. 代码块锁
public void method() {
synchronized(this) { // 锁对象可以是任意对象
// 临界区代码
}
}

// ========== Lock ==========
private final Lock lock = new ReentrantLock();

public void lockMethod() {
lock.lock(); // 必须手动加锁
try {
// 临界区代码
} finally {
lock.unlock(); // 必须放在finally中保证释放
}
}
​3. 核心功能对比​
功能​​synchronized​​Lock​​可中断锁​❌ 不可中断✅lockInterruptibly()​尝试获取锁​❌ 不支持✅tryLock()/tryLock(timeout)​公平锁​❌ 只有非公平锁✅ 可构造公平锁(new ReentrantLock(true))​多条件变量​❌ 单条件(wait()/notify())✅ 多个Condition对象​锁绑定多条件​❌ 不能✅lock.newCondition()​锁释放​自动释放(代码块结束/异常)必须手动调用unlock()

​4. 性能差异​

  • ​Java 5 之前​:synchronized 性能远低于 Lock(线程阻塞涉及内核态切换)
  • ​Java 6 及以后​:
  • synchronized 引入锁升级机制​(偏向锁→轻量级锁→重量级锁)
  • 两者性能差距大幅缩小
  • 建议:
  • ​简单场景​ → 优先用 synchronized(简洁安全)
  • ​复杂场景​ → 用 Lock(利用高级功能)
    ​5. 锁升级过程(synchronized优化)​​
    图片代码首次获取锁其他线程竞争自旋超过阈值无锁状态偏向锁轻量级锁:自旋适应重量级锁:线程阻塞
    ​6. 条件变量对比​
    // ===== synchronized 单条件 =====
    synchronized(lockObj) {
    while(!condition) lockObj.wait(); // 只能使用一个条件
    // 业务代码
    lockObj.notifyAll();
    }

// ===== Lock 多条件 =====
private final Condition notEmpty = lock.newCondition();
private final Condition notFull = lock.newCondition();

// 生产者
lock.lock();
try {
while(queue.isFull()) notFull.await(); // 特定条件等待
// 生产操作
notEmpty.signal(); // 唤醒特定条件
} finally { lock.unlock(); }

// 消费者
lock.lock();
try {
while(queue.isEmpty()) notEmpty.await();
// 消费操作
notFull.signal();
} finally { lock.unlock(); }
​7. 适用场景总结​
场景​​推荐方案​​原因​简单同步(如单方法加锁)✅ synchronized代码简洁,自动释放需要等待超时/中断响应✅ LocktryLock(timeout)/lockInterruptibly()分组唤醒线程✅ Lock + Condition精确控制不同等待队列公平锁需求✅ ReentrantLock(true)synchronized 只能是非公平锁需要锁统计信息✅ ReentrantLock可获取等待线程数等状态简单读写分离✅ synchronized如果写操作简单,可用同步方法代替读写锁

​8. 关键差异总结​
维度​​synchronized​​Lock​​本质​JVM 原生特性Java API 接口​死锁恢复​需外部干预(重启/JDKTools)可用tryLock防止死锁​代码控制​自动管理需要显式声明lock()和unlock()​灵活性​基础同步功能提供细粒度控制能力​监控​JConsole可查看Monitor状态可编程获取锁状态(如getQueueLength())​分布式扩展​不支持可通过Redisson等实现分布式锁

💡 ​最终建议​:

  • 优先用 ​synchronized​(简洁安全,JVM持续优化)
  • 遇到以下需求时改用 ​Lock​:
    ✦ 需要等待超时/中断响应
    ✦ 分组唤醒线程
    ✦ 公平锁需求
    ✦ 需要获取锁的详细信息

锁升级过程中什么是偏向锁→轻量级锁→重量级锁?什么是自旋?

锁升级过程详解(从偏向锁→轻量级锁→重量级锁)
​1. 偏向锁(Biased Locking)​​

  • ​目的​:消除无竞争情况下的同步开销
  • ​适用场景​:单线程多次访问同步块
  • ​实现原理​:
    // 对象头存储结构
    |-------------------------------------------------------|
    | Mark Word (64 bits) |
    |-------------------------------------------------------|
    | unused:25 | identity_hashcode:31 | unused:1 | age:4 | biased_lock:1 | lock:2 |
    |-------------------------------------------------------|
  • 首次获取锁时,JVM将线程ID写入对象头(biased_lock=1, lock=01)
  • 后续进入同步块时直接比对线程ID,无需CAS操作
  • ​特点​:
  • 只需一次CAS开销(首次)
  • 单线程重复访问无同步成本
  • ​示例​:
    synchronized(lock) { /* 第1次进入:CAS设置偏向锁 / }
    synchronized(lock) { /
    第2次进入:直接检查线程ID */ }
    ​2. 轻量级锁(Lightweight Locking)​​
  • ​触发条件​:第二个线程尝试获取锁(偏向锁撤销)
  • ​实现原理​:
    a.JVM在线程栈帧中创建Lock Record
    b.复制对象头到Lock Record(Displaced Mark Word)
    c.CAS尝试将对象头替换为指向Lock Record的指针
    d.成功获取锁(lock状态置为00)
  • ​锁竞争处理​:
    while (true) {
    if (尝试CAS成功) { break; }
    else if (自旋超过阈值) { 升级为重量级锁 }
    else { continue; } // 继续自旋
    }
  • ​特点​:
  • 通过自旋避免线程阻塞
  • 适合短时间持有锁的场景
  • 自旋消耗CPU但减少线程切换
    ​3. 重量级锁(Heavyweight Locking)​​
  • ​触发条件​:自旋失败或等待线程数过多
  • ​实现原理​:
    图片代码Object Header指向Monitor对象Owner:持有锁的线程EntryList:竞争队列WaitSet:等待队列
  • 依赖操作系统的互斥量(mutex)
  • 未获锁线程直接阻塞(用户态→内核态切换)
  • ​特点​:
  • 开销大(涉及上下文切换)
  • 防止CPU空转
  • 支持更复杂的同步机制

​自旋(Spinning)详解​
​1. 核心思想​

  • ​不阻塞线程,而是在循环中重试获取锁

  • 示例自旋锁实现:
    public class SpinLock {
    private AtomicReference owner = new AtomicReference<>();

    public void lock() {
    Thread t = Thread.currentThread();
    while (!owner.compareAndSet(null, t)) {
    // 空循环重试(自旋)
    }
    }

    public void unlock() {
    owner.set(null);
    }
    }
    ​2. 自旋策略​
    策略类型​​描述​​实现​​固定次数自旋​设置固定重试次数for (int i=0; i<MAX_SPIN; i++)​自适应自旋​JVM根据历史成功率动态调整自旋时间HotSpot默认策略​条件自旋​结合条件变量避免无限自旋while (!condition && spins>0)

​3. 开销分析​
场景​​CPU开销​​延迟​​适用性​自旋成功低极低✅ 理想情况自旋失败高中⚠️ 浪费CPU资源阻塞/唤醒低高⚠️ 上下文切换开销大

​4. 最佳实践​
1.​短任务优先自旋​
if (!lock.tryLock()) {
for (int i=0; i<MAX_SPIN; i++) { // 限制自旋次数
if (lock.tryLock()) return;
}
lock.lock(); // 自旋失败后阻塞
}
2.​结合条件检查​
while (true) {
if (tryAcquireLock()) break;
if (needToBlock()) {
parkThread(); // 放弃自旋
break;
}
}
3.​JVM自适应优化​

  • 历史数据:统计锁持有时间
  • 动态调整:自旋时间 ≈ 上次持有时间 * 系数
  • 平台相关:单核CPU直接禁用自旋


​关键点总结​
1.​锁升级​

  • 目标:最小化同步开销
  • 路径:无锁 → 偏向锁 → 轻量级锁 → 重量级锁
  • 不可逆:重量级锁无法降级(部分JVM支持降级但成本高)
    2.​自旋优化​
  • 目的:避免用户态→内核态切换
  • 权衡:CPU时间 vs 上下文切换开销
  • 临界点:锁持有时间 ≈ 线程切换时间 * 2
    💡 ​实战建议​:
    undefined.减少竞争:缩小同步块范围
    undefined.分离热点:读写锁分离(如ConcurrentHashMap)
    undefined.避免升级:控制锁持有时间短于自旋阈值
    undefined.监控工具:jstack -l 检查锁状态

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/95670.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/95670.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/95670.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Pie Menu Editor V1.18.7.exe 怎么安装?详细安装教程(附安装包)​

​​Pie Menu Editor V1.18.7.exe​ 是一款用于创建和编辑 ​饼图菜单&#xff08;Pie Menu&#xff09;​​ 的工具软件&#xff0c;通常用于游戏开发、UI设计、3D建模&#xff08;如 Blender 等&#xff09;、或自定义软件操作界面。 一、准备工作 ​下载文件​ 下载了 ​Pi…

基于Spark的中文文本情感分析系统研究

引言 1.1 研究背景与意义 随着互联网的普及和社交媒体的兴起、特别是自媒体时代的来临&#xff0c;网络文本数据呈现爆炸式增长。这些文本数据蕴含着丰富的用户情感信息&#xff0c;如何有效地挖掘和利用这些信息&#xff0c;对于了解舆情动态、改进客户服务、辅助决策分析具…

Simulink子系统、变体子系统及封装知识

1.引言 文章三相新能源并网系统序阻抗模型——序阻抗分析器IMAnalyzer介绍了一种用于分析和扫描序阻抗的软件。其中&#xff0c;在序阻抗扫频操作过程中&#xff0c;用到了一个扰动注入、测量和运算工具【IMtool】&#xff0c;它外表长这样&#xff1a; 内部长这样&#xff1a…

高阶组件介绍

高阶组件约定俗成以with开头 import React, { useEffect } from react; import { TouchableOpacity, Image, StyleSheet } from react-native;type IReactComponent React.ClassicComponentClass| React.ComponentClass| React.FunctionComponent| React.ForwardRefExoticComp…

C++ STL系列-02.泛型入门

C STL系列-02.泛型入门C中的泛型编程主要通过模板&#xff08;template&#xff09;实现。模板允许我们编写与类型无关的代码&#xff0c;是一种将类型作为参数进行编程的方式。在C中&#xff0c;模板分为函数模板和类模板。 1. 函数模板函数模板允许我们定义一个函数&#xff…

高效管理网络段和端口集合的工具之ipset

目录 1. 核心命令速查 2. 集合类型 3. 实战案例&#xff1a;使用 ipset 封禁 IP 案例 1&#xff1a;基础黑名单封禁&#xff08;手动添加&#xff09; 案例 2&#xff1a;自动过期和解封 案例 3&#xff1a;封禁 IP 和端口组合 案例 4&#xff1a;白名单模式 案例 5&am…

实例和对象的区别

对象&#xff08;Object&#xff09;是一个概念&#xff0c;它表示“某个类的一个成员”&#xff0c;是“逻辑上的个体”。实例&#xff08;Instance&#xff09;是一个现实&#xff0c;指的是在内存中真正分配了空间的对象。实例一定是对象&#xff0c;但对象不一定是实例。例…

Win10 Chrome认不出新Emoji?两个扩展搞定显示与输入

前言 用Win10电脑在Chrome里发消息、刷网页时&#xff0c;你是否遇到过这样的尴尬&#xff1a;别人发的、或者页面显示的 Emoji&#xff0c;在你屏幕上变成了空白方框&#xff0c;像“文字里缺了一块拼图”&#xff1f;其实这不是Chrome的错&#xff0c;也不用换电脑&#xff0…

Golang中逃逸现象, 变量“何时栈?何时堆?”

目录 什么是栈 什么是堆 栈 vs 堆&#xff08;核心区别&#xff09; GO编译器的逃逸分析 什么是逃逸分析&#xff1f; 怎么看逃逸分析结果&#xff1f; 典型“会逃逸”的场景 闭包捕获局部变量 返回或保存带有“底层存储”的容器 经由接口/反射/fmt 等导致装箱或被长…

MySQL入门指南:从安装到工作原理

什么是MySQL MySQL是一个开源的关系型数据库管理系统&#xff0c;由瑞典MySQL AB公司开发&#xff08;目前属于Oracle公司&#xff09;&#xff0c;被广泛地应用在大中小型网站中 MySQL是一个小型的开源的关系型数据库管理系统&#xff0c;与其他大型数据库管理系统例如&…

dask.dataframe.shuffle.set_index中获取 divisions 的步骤分析

dask.dataframe.shuffle.set_index 中获取 divisions 的步骤分析 主要流程概述 在 set_index 函数中&#xff0c;当 divisionsNone 时&#xff0c;系统需要通过分析数据来动态计算分区边界。这个过程分为以下几个关键步骤&#xff1a; 1. 初始检查和准备 if divisions is None:…

ai生成ppt工具有哪些?10款主流AI生成PPT工具盘点

随着人工智能技术的飞速发展&#xff0c;AI生成PPT工具逐渐成为职场人士、学生和创作者提升效率的得力助手。这类工具通过智能算法&#xff0c;能够快速将文本、数据或创意转化为结构化、视觉化的演示文稿&#xff0c;大幅节省设计时间。1、AiPPT星级评分&#xff1a;★★★★★…

Qt多线程编程学习

Qt多线程编程学习 1. 项目概述 本项目展示了Qt中多线程编程的基本用法&#xff0c;通过继承QThread类创建自定义线程&#xff0c;并演示了线程的启动、执行和销毁过程。项目包含一个简单的用户界面&#xff0c;用户可以通过按钮控制线程的启动和结束。 1.1 项目结构 项目包含以…

加密货币武器化:恶意npm包利用以太坊智能合约实现隐蔽通信

ReversingLabs研究人员发现两个恶意npm包利用以太坊&#xff08;Ethereum&#xff09;智能合约隐藏并传播恶意软件。这两个名为colortoolsv2和mimelib2的软件包于2025年7月被识别&#xff0c;展现了开源安全攻防战中的新战术。恶意软件包伪装成实用工具攻击活动始于7月7日发布的…

Spring Boot 全局字段处理最佳实践

在日常开发中&#xff0c;我们总会遇到一些琐碎但又无处不在的字段处理需求&#xff1a;• 请求处理: 用户提交的表单&#xff0c;字符串前后带了多余的空格&#xff0c;需要手动 trim()。• 响应处理: 返回给前端的 BigDecimal 金额&#xff0c;因为精度问题导致JS处理出错&am…

三坐标测量机在汽车制造行业中的应用

在汽车制造业中&#xff0c;零部件精度决定着整车性能。从发动机活塞的微米级公差&#xff0c;到车身焊接的毫米级间隙&#xff0c;汽车制造“差之毫厘&#xff0c;谬以千里” &#xff0c;任何细微偏差都可能引发连锁反应&#xff1a;发动机抖动、异响、油耗飙升&#xff0c;车…

机床夹具设计 +选型

机床夹具设计—第2组&#xff08;钻床夹具&#xff09;仿真组装视频_哔哩哔哩_bilibili 夹具-商品搜索-怡合达一站式采购平台 米思米FA标准品电子目录new 可能要吧这些定位块单独用yolo训练一边才能搞识别分析 3长条一短销定位&#xff0c;黄色的用来夹紧 一个面加一短轴一棱…

表格识别技术:通过计算机视觉和OCR,实现非结构化表格向结构化数据的转换,推动数字化转型。

在日常工作和生活中&#xff0c;我们无处不在与表格打交道。从财务报表、发票收据&#xff0c;到科研论文中的数据表、医疗报告&#xff0c;表格以其清晰、结构化的方式&#xff0c;承载着大量关键信息。然而&#xff0c;当这些表格以纸质或图片等非结构化形式存在时&#xff0…

Go基础(②Viper)

Viper 读取配置创建一个配置文件 config.yamlserver:port: 8080timeout: 30 # 超时时间&#xff08;秒&#xff09; database:host: "localhost"user: "root"password: "123456"name: "mydb"然后用 Viper 读取这个配置&#xff0c;代…

kafka Partition(分区)详解

一、什么是 PartitionPartition&#xff08;分区&#xff09; 是 Kafka Topic&#xff08;主题&#xff09; 的最小并行单位。一个 Topic 可以包含多个 Partition&#xff0c;每个 Partition 底层对应一个有序、不可变的消息队列&#xff0c;消息只会顺序追加。Partition 内部消…