Java 阻塞队列

阻塞队列简介

阻塞队列的历史

Java 阻塞队列的历史可以追溯到 JDK1.5 版本,当时 Java 平台增加了 java.util.concurrent,即我们常说的 JUC 包,其中包含了各种并发流程控制工具、并发容器、原子类等。这其中自然也包含了我们这篇文章所讨论的阻塞队列。

为了解决高并发场景下多线程之间数据共享的问题,JDK1.5 版本中出现了 ArrayBlockingQueueLinkedBlockingQueue,它们是带有生产者-消费者模式实现的并发容器。其中,ArrayBlockingQueue 是有界队列,即添加的元素达到上限之后,再次添加就会被阻塞或者抛出异常。而 LinkedBlockingQueue 则由链表构成的队列,正是因为链表的特性,所以 LinkedBlockingQueue 在添加元素上并不会向 ArrayBlockingQueue 那样有着较多的约束,所以 LinkedBlockingQueue 设置队列是否有界是可选的(注意这里的无界并不是指可以添加任务数量的元素,而是说队列的大小默认为 Integer.MAX_VALUE,近乎于无限大)。

阅读更多

ConcurrentHashMap 为什么不允许key和value为null

在Java中,ConcurrentHashMap是一种线程安全的哈希表实现,广泛用于并发编程场景中。与传统的HashMap不同,ConcurrentHashMap不允许null键或null值。这种设计并非随意而为,而是经过深思熟虑的决定。


1. 并发操作中的歧义问题

1.1 null键的歧义

ConcurrentHashMap中,如果允许null键,当我们调用map.get(null)时,返回null意味着什么?

阅读更多

Java ConcurrentHashMap

ConcurrentHashMap 1.7

存储结构

Java 7 ConcurrentHashMap 存储结构

Java 7 中 ConcurrentHashMap 的存储结构如上图,ConcurrnetHashMap 由很多个 Segment 组合,而每一个 Segment 是一个类似于 HashMap 的结构,所以每一个 HashMap 的内部可以进行扩容。但是 Segment 的个数一旦初始化就不能改变,默认 Segment 的个数是 16 个,你也可以认为 ConcurrentHashMap 默认支持最多 16 个线程并发。

阅读更多

Java 集合研究


允许存储 null 的集合

List 接口的实现类

  • **ArrayList**:允许 null
  • **LinkedList**:允许 null
阅读更多

Java集合使用经验

集合判空

《阿里巴巴 Java 开发手册》的描述如下:

判断所有集合内部的元素是否为空,使用 isEmpty() 方法,而不是 size()==0 的方式。

这是因为 isEmpty() 方法的可读性更好,并且时间复杂度为 O(1)

绝大部分我们使用的集合的 size() 方法的时间复杂度也是 O(1),不过,也有很多复杂度不是 O(1) 的,比如 java.util.concurrent 包下的 ConcurrentLinkedQueueConcurrentLinkedQueueisEmpty() 方法通过 first() 方法进行判断,其中 first() 方法返回的是队列中第一个值不为 null 的节点(节点值为null的原因是在迭代器中使用的逻辑删除)

阅读更多

关于Spring 与 Spring Boot 的一些图

Spring Framework 启动流程

1. 流程图

以下流程图展示了 Spring Framework 从创建 ApplicationContext 到完成初始化的关键步骤。

flowchart TD
    A[启动入口: main 方法] --> B[创建 AnnotationConfigApplicationContext]
阅读更多

Spring Framework 与 Spring Boot 启动对比

Spring Boot 和 Spring Framework 都是构建现代 Java 企业级应用程序的强大工具。Spring Boot 基于 Spring Framework 之上,旨在简化 Spring 应用的创建和配置过程。尽管两者在启动流程上存在许多相似之处,但 Spring Boot 引入了一些额外的机制和约定,以提高开发效率和应用的可扩展性。以下将详细对比两者的启动流程,强调它们的异同点,并结合源码角度进行说明。

目录

  1. 总体架构对比
阅读更多

Spring Boot 启动流程分析

Spring Boot 简化了基于 Spring 的应用程序的创建和部署过程,其启动流程涉及多个步骤和组件。为了详细理解 Spring Boot 的启动流程,我们可以从源码的角度进行分析。以下是 Spring Boot 启动过程的详细介绍,结合关键源码类和方法进行说明。

应用程序的入口点

通常,Spring Boot 应用程序的启动入口是一个带有 main 方法的类,该类使用 @SpringBootApplication 注解。例如:

1
2
3
4
5
6
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
阅读更多

Spring Framework 启动流程分析

Spring Framework 是一个功能强大且灵活的用于构建企业级 Java 应用程序的框架。理解 Spring Framework 的启动流程对于深入掌握其工作机制、调试应用程序以及进行高级定制非常重要。本文将详细介绍 Spring Framework 的启动流程,并结合关键源码类和方法进行说明。

应用程序的入口点

在 Spring Framework 中,应用程序的启动通常涉及创建和配置一个 ApplicationContext。常见的方式包括使用 ClassPathXmlApplicationContextAnnotationConfigApplicationContext 或通过 ContextLoader 在 Web 应用中加载上下文。

阅读更多

Spring Cloud 动态路由实现方案

目前Spring Cloud的路由网关方案主要是:Spring Cloud Gateway。默认便有自动更新路由的实现。通过 RouteRefreshListener 检测到更新条件发送 RefreshRoutesEvent 事件实现。更新条件:在服务启动时、新服务注册时、配置中心配置修改时、心跳更新时都会触发。

下面说下自己实现的方案,可以根据自身情况,自定义路由定义实体类。

使用Nacos配置监听方式

思路:监听配置变化,然后 RouteDefinitionWriter 更新路由规则。

阅读更多