摘要:
foreach 背后 平常我们循环一个 List 大概有下面这三种方式: 传统 for 循环 for (int i = 0; i < list.size(); i++) { } 用迭代器进行迭代遍历 Iterator itr = list.iterator(); while (itr.hasNext 阅读全文
摘要:
作用 HashMap 在多线程环境中,扩容的时候可能会死循环;HashTable 只是简单粗暴的在方法上用 synchronized 进行同步,同一时刻,只会有一个线程获取到锁,其他线程全部阻塞(也有可能自旋),性能堪忧。所以 ConcurrentHashMap 诞生了。 结构 Concurrent 阅读全文
摘要:
分析 LinkedHashMap是HashMap的子类,也就是说它与HashMap具有相同存储结构,不同的是,LinkedHashMap加入了一个双向循环链表,链表的头结点是一个不保存数据的head节点。 /** * The head of the doubly linked list. */ pr 阅读全文
摘要:
看完HashMap内部的数据结构(数组+链表)和put get的过程,就没再去关注太多。今天脑子里就突然冒出 map 遍历的代码: for(Map.Entry<K, V> entry : map.entrySet()) { } 以前一直以为entrySet()方法就是 HashMap 内部维护了一个 阅读全文
摘要:
你需要知道 HashMap内部使用一个数组来存储数据,数组的元素是一个叫Entry的静态内部类,该类不过也只是implements了定义在Map中的Entry接口。 Entry的属性: static class Entry<K,V> implements Map.Entry<K,V> { final 阅读全文
摘要:
何时该用 MQ 大致可以分为下面四种场景 削峰限流:当上游能力远大于下游处理能力 数据驱动的任务依赖:任务之间有一定的依赖关系 上游不关心下游执行结果:解耦 异步返回执行时间长:离线处理,或者跨公网调用等 不应该使用 MQ 上游实时关注执行结果 保证消息不丢失 以 RabbitMQ 为例 生产者开启 阅读全文
摘要:
RabbitMQ 的持久化分为三个部分: 交换器的持久化 队列的持久化 消息的持久化 交换器的持久化 交换器的持久化是在声明交换器时将 durable 设为 true。如果交换器没有设置持久化,那么 RabbitMQ 宕机重启后,交换器相关的元数据会丢失,不过相关的消息不会丢失,只是不能将消息发送到 阅读全文
摘要:
持久化虽然能解决 RabbitMQ 宕机数据丢失问题,但还有个问题就是,消息到底有没有正确到达服务器呢。如果不进行特殊配置,消息发送出去后,是没有任何操作来告诉生产者消息是否到达服务器。消息在到达服务器之前就丢失了,持久化也解决不了问题。因为消息都没有,谈何持久化。 RabbitMQ 为了针对这个问 阅读全文
摘要:
通过上篇《【RabbitMQ 笔记】— 死信队列》的了解,我们知道队列中的消息过期后会被 RabbitMQ 转发到 DLX(前提是要为队列添加 DLX),进而路由到死信队列。而正好可以利用这个功能(DLX + TTL)来实现延时队列,废话不多说,先看图 图中为每个过期时间设置了单独的队列,比如 qu 阅读全文
摘要:
死信交换器,Dead Letter Exchange,下文简称 DLX。当消息在一个队列中变成死信(Dead Letter)之后,它会被发送到另一个交换器中,这个交换器就是 DLX,绑定 DLX 的队列就称为死信队列。 消息变成死信一般由以下几种情况: 消息被拒绝(Basic.Reject / Ba 阅读全文
摘要:
通过上一篇【RabbitMQ 笔记】— 基本概念,知道生产者和消费者使用到的主要类和接口有 ConnectionFactory、Connection、Channel、Consumer 等。Connection 是用来开启 Channel 的,RabbitMQ 开发工作也基本上是围绕 Connecti 阅读全文
摘要:
RabbitMQ 整体上是一个生产者消费者模型,主要负责接收、存储和转发消息。整体模型架构图如下: 生产者和消费者 生产者 Producer:生产者,就是投递消息的一方。生产者创建消息,然后发布到 RabbitMQ 中。 消息一般可以分为两部分: 消息体(payload):带有业务逻辑结构的数据,比 阅读全文