2.多线程并发

article/2025/10/7 18:46:23

1.说说你知道的创建线程的方式

  • 1、继承Thread类,重写run方法。
  • 2、实现Runnable接口,重写run方法。
  • 3、实现Callable接口,重写call方法。
  • 4、通过线程池创建线程。
    https://blog.csdn.net/u013541140/article/details/95225769
    CachedThreadPool:可缓存的线程池,该线程池中没有核心线程,非核心线程的数量为Integer.max_value,就是无限大,当有需要时创建线程来执行任务,没有需要时回收线程,适用于耗时少,任务量大的情况。

SecudleThreadPool:周期性执行任务的线程池,按照某种特定的计划执行线程中的任务,有核心线程,但也有非核心线程,非核心线程的大小也为无限大。适用于执行周期性的任务。

SingleThreadPool:只有一条线程来执行任务,适用于有顺序的任务的应用场景。

FixedThreadPool:定长的线程池,有核心线程,核心线程的即为最大的线程数量,没有非核心线程

我们在用阿里巴巴代码检测工具检测时 “线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。

public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler)

corePoolSize:线程池中的线程数量;
maximumPoolSize:线程池中的最大线程数量;
keepAliveTime:当线程池线程数量超过corePoolSize时,多余的空闲线程会在多长时间内被销毁;
unit:keepAliveTime的时间单位;
workQueue:任务队列,被提交但是尚未被执行的任务;
threadFactory:线程工厂,用于创建线程,一般情况下使用默认的,即Executors类的静态方法defaultThreadFactory();handler:拒绝策略。当任务太多来不及处理时,如何拒绝任务
https://blog.csdn.net/bojikeqian/article/details/120946609

2.说说Callable

Callable的call方法提供返回值,所以当你需要知道任务执行的结果时,Callable是个不错的选择。
Callable任务通过线程池的submit方法提交

class IntegerCallableTask implements Callable<Integer> {@Overridepublic Integer call() throws Exception {int sum = 0;for (int i = 0; i < 520; i++) {sum += i;}return sum;}
}

Callable任务通过线程池的submit方法提交。且submit方法返回Future对象,通过Future的get方法可以获得具体的计算结果。而且get是个阻塞的方法,如果任务未执行完,则一直等待。

        ExecutorService executor = Executors.newCachedThreadPool();IntegerCallableTask integerCallableTask = new IntegerCallableTask();Future<Integer> future = executor.submit(integerCallableTask);executor.shutdown();try {System.out.println(future.get());} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}

对于Calleble来说,Future和FutureTask均可以用来获取任务执行结果,不过Future是个接口,FutureTask是Future的具体实现,而且FutureTask还间接实现了Runnable接口,也就是说FutureTask可以作为Runnable任务提交给线程池。

3 如何控制线程执行的顺序?

3.1 方法一:join

public class Test {public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(new MyThread1());Thread t2 = new Thread(new MyThread2());Thread t3 = new Thread(new MyThread3());t1.start();t1.join();t2.start();t2.join();t3.start();}
}class MyThread1 implements Runnable {@Overridepublic void run() {System.out.println("I am thread 1");}
}class MyThread2 implements Runnable {@Overridepublic void run() {System.out.println("I am thread 2");}
}class MyThread3 implements Runnable {@Overridepublic void run() {System.out.println("I am thread 3");}
}

join方法:让主线程等待子线程运行结束后再继续运行

有了join方法的帮忙,线程123就能按照指定的顺序执行了。

我们来看看示例当中主线程与子线程的执行顺序。在main方法中,先是调用了t1.start方法,启动t1线程,随后调用t1的join方法,main所在的主线程就需要等待t1子线程中的run方法运行完成后才能继续运行,所以主线程卡在t2.start方法之前等待t1程序。等t1运行完后,主线程重新获得主动权,继续运行t2.start和t2.join方法,与t1子线程类似,main主线程等待t2完成后继续执行,如此执行下去,join方法就有效的解决了执行顺序问题。因为在同一个时间点,各个线程是同步状态。

3.2 Excutors.newSingleThreadExecutor()

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class Test {private static ExecutorService executor = Executors.newSingleThreadExecutor();public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(new MyThread1());Thread t2 = new Thread(new MyThread2());Thread t3 = new Thread(new MyThread3());executor.submit(t1);executor.submit(t2);executor.submit(t3);executor.shutdown();}
}class MyThread1 implements Runnable {@Overridepublic void run() {System.out.println("I am thread 1");}
}class MyThread2 implements Runnable {@Overridepublic void run() {System.out.println("I am thread 2");}
}class MyThread3 implements Runnable {@Overridepublic void run() {System.out.println("I am thread 3");}
}

利用并发包里的Excutors的newSingleThreadExecutor产生一个单线程的线程池,而这个线程池的底层原理就是一个先进先出(FIFO)的队列。代码中executor.submit依次添加了123线程,按照FIFO的特性,执行顺序也就是123的执行结果,从而保证了执行顺序。

4.用户线程与守护线程

用户(User)线程:运行在前台,执行具体任务,如程序的主线程,连接网络的子线程都是用户线程。
守护(Daemon)线程:运行在后台,为其它前台线程服务,也可以说守护线程是JVM非守护线程的”佣人“,一旦所有线程都执行结束,守护线程会随着JVM一起结束运行。
main函数就是一个用户线程,main函数启动时,同时JVM还启动了好多的守护线程,如垃圾回收线程,比较明显的区别时,用户线程结束,JVM退出,不管这个时候有没有守护线程的运行,都不会影响JVM的退出。

5线程死锁

5.1什么是线程死锁

死锁是指两个或两个以上进程(线程)在执行过程中,由于竞争资源或由于彼此通信造成的一种堵塞的现象,若无外力的作用下,都将无法推进,此时的系统处于死锁状态。
如图,线程A拥有的资源2,线程B拥有的资源1,此时线程A和线程B都试图去拥有资源1和资源2,但是它们的🔒还在,因此就出现了死锁。
在这里插入图片描述

5.2 形成死锁的四个必要条件

  • 互斥条件:线程(进程)对所分配的资源具有排它性,即一个资源只能被一个进程占用,直到该进程被释放。
  • 请求与保持条件:一个进程(线程)因请求被占有资源而发生堵塞时,对已获取的资源保持不放。
  • 不剥夺条件:线程(进程)已获取的资源在未使用完之前不能被其他线程强行剥夺,只有等自己使用完才释放资源。
  • 循环等待条件:当发生死锁时,所等待的线程(进程)必定形成一个环路,死循环造成永久堵塞。

5.3如何避免死锁

  • 1、加锁顺序。
    当多个线程需要相同的一些锁,但是按照不同的顺序加锁,死锁就很容易发生。如果能确保所有的线程都是按照相同的顺序获得锁,那么死锁就不会发生
  • 2、加锁时限
    另外一个可以避免死锁的方法是在尝试获取锁的时候加一个超时时间,这也就意味着在尝试获取锁的过程中若超过了这个时限该线程则放弃对该锁请求。若一个线程没有在给定的时限内成功获得所有需要的锁,则会进行回退并释放所有已经获得的锁,然后等待一段随机的时间再重试。
    单体应用锁一般是用 synchronizedvolatile
    分布式锁 redisson实现的redis锁

6.ThreadLocal

https://blog.csdn.net/qq_35190492/article/details/107599875

7 线程声明周期的6种状态

在这里插入图片描述

8 阿里巴巴Java开发手册推荐线程池的创建方式你知道吗

之前在项目中做一些任务型的项目,采用多线程方式,笔者通常用ExecutorService cachedThreadPool=Executors.newFixedThreadPool();方式创建。但是后来看阿里巴巴的JAVA开发手册,上面有个建议:【强制】线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。那么线程池的原理是什么样的?创建方式是什么样的呢?接下来让我们看看。

public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler) 

参数解释:

corePoolSize : 线程池核心池的大小。
maximumPoolSize : 线程池的最大线程数。
keepAliveTime : 当线程数大于核心时,此为终止前多余的空闲线程等待新任务的最长时间。
unit : keepAliveTime 的时间单位。
workQueue : 用来储存等待执行任务的队列。
threadFactory : 线程工厂。
handler 拒绝策略。
https://blog.csdn.net/jek123456/article/details/90601351
https://blog.csdn.net/K_520_W/article/details/108992698

其他面试题
https://blog.csdn.net/JAYU_37/article/details/106321844

https://blog.csdn.net/m0_45270667/article/details/108598282

JUC面试题

https://blog.csdn.net/Piratesa/article/details/102710342
https://blog.csdn.net/weixin_44018338/article/details/105600264

锁机制

https://blog.csdn.net/qq_41181619/article/details/81407289

https://developer.aliyun.com/article/607025

9 JMM

java内存模型:为什么会有JMM呢
JVM实现不同会造成“翻译”的效果不同,不同CPU平台的机器指令有千差万别,无法保证同一份代码并发下的效果一致。所以需要一套统一的规范来约束JVM的翻译过程,保证并发效果一致性
在这里插入图片描述
三个特性

  • 原子性
  • 有序性
  • 可见性

ReentrantLock

是一个悲观锁 仔细看代码发现ReentrantLock使用了setExclusiveOwnerThread方法,
这个方法是将某一个线程设置为独占线程。就是我们常说的互斥锁。

AQS:也就是队列同步器,这是实现 ReentrantLock 的基础。

AQS 有一个 state 标记位,值为1 时表示有线程占用,其他线程需要进入到同步队列等待,同步队列是一个双向链表。
在这里插入图片描述
当获得锁的线程需要等待某个条件时,会进入 condition 的等待队列,等待队列可以有多个。

当 condition 条件满足时,线程会从等待队列重新进入同步队列进行获取锁的竞争。

ReentrantLock 就是基于 AQS 实现的,如下图所示,ReentrantLock 内部有公平锁和非公平锁两种实现,差别就在于新来的线程是否比已经在同步队列中的等待线程更早获得锁。

是针对获取锁而言的,如果一个锁是公平的,那么锁的获取顺序就应该符合请求上的绝对时间顺序,满足FIFO(First In First Out).公平锁每次都是从同步队列中的第一个节点获取到锁,而非公平性锁则不一定,有可能刚释放锁的线程能再次获取到锁。

synchronized

1 . synchronized的特点
一个线程执行互斥代码过程如下:

  1. 获得同步锁;
  2. 清空工作内存;
  3. 从主内存拷贝对象副本到工作内存;
  4. 执行代码(计算或者输出等);
  5. 刷新主内存数据;
  6. 释放同步锁。
    所以,synchronized既保证了多线程的并发有序性,又保证了多线程的内存可见性

同步代码原理:

当我们进入一个人方法的时候,执行monitorenter,就会获取当前对象的一个所有权,这个时候monitor进入数为1,当前的这个线程就是这个monitor的owner。

如果你已经是这个monitor的owner了,你再次进入,就会把进入数+1.

同理,当他执行完monitorexit,对应的进入数就-1,直到为0,才可以被其他线程持有。

同步方法原理:

不知道大家注意到方法那的一个特殊标志位没,ACC_SYNCHRONIZED。

同步方法的时候,一旦执行到这个方法,就会先判断是否有标志位,然后,ACC_SYNCHRONIZED会去隐式调用刚才的两个指令:monitorenter和monitorexit。

所以归根究底,还是monitor对象的争夺。

volatile

volatile可以保证内存可见性,并发有序性(不具有原子性)。
volatile可以保证线程可见性且提供了一定的有序性,但是无法保证原子性。在JVM底层volatile是采用“内存屏障”来实现的。观察加入volatile关键字和没有加入volatile关键字时所生成的汇编代码发现,加入volatile关键字时,会多出一个lock前缀指令,lock前缀指令实际上相当于一个内存屏障(也成内存栅栏),内存屏障会提供3个功能:

(1)它确保指令重排序时不会把其后面的指令排到内存屏障之前的位置,也不会把前面的指令排到内存屏障的后面;即在执行到内存屏障这句指令时,在它前面的操作已经全部完成;

(2)它会强制将对缓存的修改操作立即写入主存;

(3)如果是写操作,它会导致其他CPU中对应的缓存行无效

锁的升级

方向是不可逆的
在这里插入图片描述

11扩展

  1. Synchronized 和 ReenTrantLock 的对比
    ① 两者都是可重入锁

两者都是可重入锁。“可重入锁”概念是:自己可以再次获取自己的内部锁。比如一个线程获得了某个对象的锁,此时这个对象锁还没有释放,当其再次想要获取这个对象的锁的时候还是可以获取的,如果不可锁重入的话,就会造成死锁。同一个线程每次获取锁,锁的计数器都自增1,所以要等到锁的计数器下降为0时才能释放锁。

② synchronized依赖于JVM而ReenTrantLock依赖于API

synchronized是依赖于JVM实现的,前面我们也讲到了 虚拟机团队在JDK1.6为synchronized关键字进行了很多优化,但是这些优化都是在虚拟机层面实现的,并没有直接暴露给我们。ReenTrantLock是JDK层面实现的(也就是API层面,需要lock()和unlock()方法配合try/finally语句块来完成),所以我们可以通过查看它的源代码,来看它是如何实现的。

③ ReenTrantLock比synchronized增加了一些高级功能

相比synchronized,ReenTrantLock增加了一些高级功能。主要来说主要有三点:①等待可中断;②可实现公平锁;③可实现选择性通知(锁可以绑定多个条件)

ReenTrantLock提供了一种能够中断等待锁的线程的机制,通过lock.lockInterruptibly()来实现这个机制。也就是说正在等待的线程可以选择放弃等待,改为处理其他事情。

ReenTrantLock可以指定是公平锁还是非公平锁。而synchronized只能是非公平锁。所谓的公平锁就是先等待的线程先获得锁。ReenTrantLock默认情况是非公平的,可以通过ReenTrantLoc类的ReentrantLock(boolean fair)构造方法来制定是否是公平的。

synchronized关键字与wait()和notify()/notifyAll()方法相结合可以实现等待/通知机制,ReentrantLock类当然也可以实现,但是需要借助于Condition接口与newCondition()方法。Condition是JDK1.5之后才有的,它具有很好的灵活性,比如可以实现多路通知功能也就是在一个Lock对象中可以创建多个Condition实例(即对象监视器),线程对象可以注册在指定的Condition中,从而可以有选择性的进行线程通知,在调度线程上更加灵活。 在使用notify/notifyAll()方法进行通知时,被通知的线程是由JVM选择的,用ReentrantLock类结合Condition实例可以实现“选择性通知” ,这个功能非常重要,而且是Condition接口默认提供的。而synchronized关键字就相当于整个Lock对象中只有一个Condition实例,所有的线程都注册在它一个身上。如果执行notifyAll()方法的话就会通知所有处于等待状态的线程这样会造成很大的效率问题,而Condition实例的signalAll()方法只会唤醒注册在该Condition实例中的所有等待线程。

12 多线程原理

https://blog.csdn.net/v123411739/article/details/106609583

13 拒绝策略和阻塞队列

https://blog.csdn.net/qq_35909080/article/details/87002367

线程池与对策的选择
https://blog.csdn.net/qq_37334150/article/details/109559195

14 Java中sleep()与wait()区别

1、每个对象都有一个锁来控制同步访问,Synchronized关键字可以和对象的锁交互,来实现同步方法或同步块。sleep()方法正在执行的线程主动让出CPU(然后CPU就可以去执行其他任务),在sleep指定时间后CPU再回到该线程继续往下执行(注意:sleep方法只让出了CPU,而并不会释放同步资源锁!!!);wait()方法则是指当前线程让自己暂时退让出同步资源锁,以便其他正在等待该资源的线程得到该资源进而运行,只有调用了notify()方法,之前调用wait()的线程才会解除wait状态,可以去参与竞争同步资源锁,进而得到执行。(注意:notify的作用相当于叫醒睡着的人,而并不会给他分配任务,就是说notify只是让之前调用wait的线程有权利重新参与线程的调度);

2、sleep()方法可以在任何地方使用;wait()方法则只能在同步方法或同步块中使用;

3、sleep()是线程线程类(Thread)的方法,调用会暂停此线程指定的时间,但监控依然保持,不会释放对象锁,到时间自动恢复;wait()是Object的方法,调用会放弃对象锁,进入等待队列,待调用notify()/notifyAll()唤醒指定的线程或者所有线程,才会进入锁池,不再次获得对象锁才会进入运行状态;

15 线程的 run() 和 start() 有什么区别?

  • 1、start方法启动了一个新的线程,而run方法不能启动一个新线程,还是在main线程下运行,程序依然是主线程一个线程在运行。

  • 2、调用start方法可以启动线程,而run方法只是thread的一个普通方法还是在主线程中执行。

  • 3、通过start()方法来启动的新线程,处于就绪(可运行)状态,并没有运行,一旦得到cpu时间片,就开始执行相应线程的run()方法,这里方法run()称为线程体,它包含了要执行的这个线程的内容,run方法运行结束,此线程随即终止。start()不能被重复调用。而run方法能被重复调用,因为它就是一个普通的成员方法。

  • 4、start方法在执行线程体中代码时,在不执行完的情况下可以进行线程切换,而run方法不能,run方法只能进行顺序执行。


http://chatgpt.dhexx.cn/article/tnkcTsPk.shtml

相关文章

C++多线程并发(一)--- 线程创建与管理

文章目录 前言一、何为并发1.1 并发与并行1.2 硬件并发与任务切换1.3 多线程并发与多进程并发 二、如何使用并发2.1 为什么使用并发2.2 在C中使用并发和多线程 三、C线程创建3.1 C11新标准多线程支持库3.2 线程创建的简单示例 更多文章&#xff1a; 前言 我们都听说过摩尔定律…

lrzsz

lrzsz是一款程序&#xff0c;在linux中可以代替ftp的上传和下载 安装lrzsz yum install -y lrzsz上传&#xff1a;rz 将文件上传到本地&#xff0c;默认上传到当前目录 该程序支持拖拽上传&#xff0c;如下图所示 上传成功后查看本地 下载&#xff1a;sz filename 例如&am…

linux之lrzsz

1、lrzsz介绍 我们利用lrzsz进行windows和linux间的文件上传下载 2、安装 在ubuntu系统下 sudo apt-get install lrzsz 在centos系统下 yum install lrzsz 3、使用 1)、windows上传文件到linux环境,使用如下命令 rz

文件传输工具rzsz

mac安装rz sz? 之前在item2上使用使用rz和sz时就直接夯住 发现是需要配置下 mac使用rz&#xff0c;sz进行文件传输(默认使用的终端为iterm2) 一、安装lrzsz brew install lrzsz 二、下载iterm2-zmodem 执行 git clone https://github.com/aikuyun/iterm2-zmodem.git cd …

【lrzsz】Linux上lrzsz的安装和使用

一、lrzsz简介 rz&#xff0c;sz是Linux/Unix同Windows进行ZModem文件传输的命令行工具。 rz 可以很方便的从客户端传文件到服务器&#xff0c;sz也可以很方便的从服务器传文件到客户端&#xff0c;就算中间隔着跳板机也不影响。 rz(receive Zmodem) sz(send Zmodem) 远程文…

Linux lrzsz 详解

和 FileZilla 功能类似用于上传文件&#xff0c;上传速度比较慢适用于比较小的文件 安装指令 $ sudo yum install lrzsz 使用方式 $ rz 注&#xff1a;1> rz 指令在那个目录就在在那个目录上传文件 2> 文件要上的目录一定要有权限&#xff0c;否则上传失败

linux rz命令安装

新搞的云服务器用SecureCRT不支持上传和下载&#xff0c;没有找到rz命令。记录一下如何安装rz/sz命令的方法。 一、工具说明 在SecureCRT这样的ssh登录软件里, 通过在Linux界面里输入rz/sz命令来上传/下载文件. 对于某些linux版本, rz/sz默认没有安装所以需要手工安装。 sz: 将…

rz sz

linux上很方便的上传下载文件工具rz和sz (本文适合linux入门的朋友) ######################################################### #《老男孩linux就业培训中心-初级班第七期第一节内容总结。 #linux上很方便的上传下载文件工具rz和sz #date:2011-06-15 #作者&#xff1a;老男…

Linux的rz命令

linux服务器rz命令上传文件 2016年09月10日 19:56:02 阅读数&#xff1a;11712 1、首先&#xff0c;要是服务器不支持rz命令的话&#xff0c;需要安装执行 yum -y install lrzsz 2、再输入rz -be命令&#xff0c;选择需要上传的本地文件

llrzsz

文章目录 官网解压配置编译安装复制到开发板并执行使用lrz从PC传开发板使用lsz从开发板传PC参考链接 今天给大家推荐一个很好用的工具。 你是不是感觉在没有网络时往linux中下载程序很麻烦&#xff08;SD卡插拔&#xff09;&#xff0c;今天就教大家怎么通过串口和linux文件系统…

linux系统下的rz、sz详解

对于linux服务器来说&#xff0c;通常我们是通过一些ssh工具进行远程访问连接的&#xff0c;而对于经常使用它的人来说&#xff0c;少不了将文件上传下载到服务器。如何能够快速的同服务器进行文件的交互尤为重要。不然每次都打开单独的ssh客户端或者ftp很是浪费时间。今天&…

linux rzsz(lrzsz)安装

lrzsz 官网入口&#xff1a;https://ohse.de/uwe/software/lrzsz.html lrzsz是一个unix通信套件提供的X&#xff0c;Y&#xff0c;和ZModem文件传输协议,可以用在windows与linux 系统之间的文件传输&#xff0c;体积小速度快。感觉可以替代ftp了 lrzsz 在线安装&#xff1a; …

【Linux】第三章Linux环境基础开发工具使用(yum+rzsz+vim+g++和gcc+gdb+make和Makefile+进度条+git)

&#x1f3c6;个人主页&#xff1a;企鹅不叫的博客 ​ &#x1f308;专栏 C语言初阶和进阶C项目Leetcode刷题初阶数据结构与算法C初阶和进阶《深入理解计算机操作系统》《高质量C/C编程》Linux ⭐️ 博主码云gitee链接&#xff1a;代码仓库地址 ⚡若有帮助可以【关注点赞收藏】…

【Linux基础】Linux软件包管理器yum的使用指南rzsz安装

【Linux基础】Linux软件包管理器yum的使用指南|rzsz安装 前言 主页&#xff1a; 潮.eth的博客_CSDN博客-C学习,C学习,数据结构and算法领域博主 Linux基础专栏&#xff1a; Linux基础_潮.eth的博客-CSDN博客 正文 文章目录 【Linux基础】Linux软件包管理器yum的使用指南|rzsz安装…

linux虚拟机rzsz安装(wget方法,自测可用)

1、mkdir /usr/local/lszrz创建文件夹后进入这个文件夹&#xff0c;使用wget https://ohse.de/uwe/releases/lrzsz-0.12.20.tar.gz --no-check-certificate下载安装包lrzsz-0.12.20.tar.gz。这里的--no-check-certificate是不进行证书验证的意思&#xff0c;我没有加这个会产生…

linux 下安装安装rzsz命令

我们在linux上部署代码的时候经常需要上传文件到linux&#xff0c;有时候也需要从linux上下载文件到本地&#xff0c;大部分人都直接借助于ftp工具&#xff0c; 然而其实我们可以直接通过rz和sz上传下载文件&#xff0c;但是rz和sz命令不是linux默认自带的命令&#xff0c;需要…

Linxux应用开发-串口下载命令rzsz交叉编译

1.1 简介 rz/sz工具是通过Zmodem协议传输文件的命令&#xff0c;常用于Linux与windows之前的数据传输。 这篇文章就介绍如何在交叉编译rz/sz命令&#xff0c;并在Linux开发板上完成测试。 1.1.1 什么是rz/sz (lsz/lrz) rz/sz 通过Zmodem协议传输数据的命令&#xff0c;通过串…

kafka消息队列使用场景

一、消息队列概述 消息队列中间件是分布式系统中重要的组件&#xff0c;主要解决应用解耦&#xff0c;异步消息&#xff0c;流量削锋等问题&#xff0c;实现高性能&#xff0c;高可用&#xff0c;可伸缩和最终一致性架构。目前使用较多的消息队列有ActiveMQ&#xff0c;RabbitM…

Springboot之Kafka

Kafka介绍 Kafka属于分布式日志系统。 主要应用场景是&#xff1a;日志收集系统和消息系统。 Kafka主要设计目标如下&#xff1a; 以时间复杂度为O(1)的方式提供消息持久化能力&#xff0c;即使对TB级以上数据也能保证常数时间的访问性能。高吞吐率&#xff0c;即使在非常廉价…

Kafka的原理、基础架构、以及使用场景详解

一&#xff1a;Kafka简介 Apache Kafka是分布式发布-订阅消息系统&#xff0c;在 kafka官网上对 kafka 的定义&#xff1a;一个分布式发布-订阅消息传递系统。 Kafka最初由LinkedIn公司开发&#xff0c;Linkedin于2010年贡献给了Apache基金会并成为顶级开源项目。主要应用场景…