DelayQueue 源码分析
DelayQueue 简介DelayQueue 是 JUC 包(java.util.concurrent)为我们提供的延迟队列,用于实现延时任务比如订单下单 15 分钟未支付直接取消。它是 BlockingQueue 的一种,底层是一个基于 PriorityQueue 实现的一个无界队列,是线程安全的。关于PriorityQueue可以参考笔者编写的这篇文章:PriorityQueue 源码分析 。
DelayQueue 中存放的元素必须实现 Delayed 接口,并且需要重写 getDelay()方法(计算是否到期)。
123public interface Delayed extends Comparable<Delayed> { long getDelay(TimeUnit unit);}
默认情况下, DelayQueue 会按照到期时间升序编排任务。只有当元素过期时(getDelay()方法返回值小于等于 0),才能从队列中取出。
DelayQueue 发展史
DelayQueue 最早是在 Java 5 中引入的,作为 java. ...
HashMap 源码分析
HashMap 简介HashMap 主要用来存放键值对,它基于哈希表的 Map 接口实现,是常用的 Java 集合之一,是非线程安全的。
HashMap 可以存储 null 的 key 和 value,但 null 作为键只能有一个,null 作为值可以有多个
JDK1.8 之前 HashMap 由 数组+链表 组成的,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的(“拉链法”解决冲突)。 JDK1.8 以后的 HashMap 在解决哈希冲突时有了较大的变化,当链表长度大于等于阈值(默认为 8)(将链表转换成红黑树前会判断,如果当前数组的长度小于 64,那么会选择先进行数组扩容,而不是转换为红黑树)时,将链表转化为红黑树,以减少搜索时间。
HashMap 默认的初始化大小为 16。之后每次扩充,容量变为原来的 2 倍。并且, HashMap 总是使用 2 的幂作为哈希表的大小。
底层数据结构分析JDK1.8 之前JDK1.8 之前 HashMap 底层是 数组和链表 结合在一起使用也就是 链表散列。
HashMap 通过 key 的 hashCode 经过扰动函数 ...
LinkedHashMap 源码分析
LinkedHashMap 简介LinkedHashMap 是 Java 提供的一个集合类,它继承自 HashMap,并在 HashMap 基础上维护一条双向链表,使得具备如下特性:
支持遍历时会按照插入顺序有序进行迭代。
支持按照元素访问顺序排序,适用于封装 LRU 缓存工具。
因为内部使用双向链表维护各个节点,所以遍历时的效率和元素个数成正比,相较于和容量成正比的 HashMap 来说,迭代效率会高很多。
LinkedHashMap 逻辑结构如下图所示,它是在 HashMap 基础上在各个节点之间维护一条双向链表,使得原本散列在不同 bucket 上的节点、链表、红黑树有序关联起来。
LinkedHashMap 使用示例插入顺序遍历如下所示,我们按照顺序往 LinkedHashMap 添加元素然后进行遍历。
123456789HashMap < String, String > map = new LinkedHashMap < > ();map.put("a", "2");map.put("g&quo ...
MVC到底是设计模式还是软件架构
软件架构概念软件架构是一个系统的蓝图,它包括多个方面,如系统的结构、行为、用户界面、组件、数据等。软件架构定义了系统的主要组成部分以及这些部分之间的交互。它是在系统设计阶段确定的,并在整个系统的生命周期中起着关键作用。
作用软件架构的主要作用是为系统的设计和实现提供一个基础框架。它定义了系统的主要组成部分以及这些部分之间的交互。软件架构可以帮助我们理解系统的高级结构,并可以指导系统的实现和维护。软件架构的抽象级别最高,它关注的是整个系统的大局。
常见的软件架构(部分)MVVM(Model-View-ViewModel)MVVM是一种特别适用于图形用户界面的架构,它将应用程序分为模型、视图和视图模型三个部分。
微服务架构在微服务架构中,应用程序被分解为一组小的、独立的服务,每个服务都可以独立地开发和部署。
设计模式概念设计模式是在面向对象软件设计中常见的、已经被证明有效的设计解决方案。设计模式可以解决在软件设计中经常出现的特定问题,它们是经验的总结,可以帮助设计者避免一些常见的错误。设计模式通常比软件架构更具体,更低级别,它们通常用于解决在特定上下文中的特定问题。
作用设计模式的主要作用 ...
LinkedList 源码分析
LinkedList 简介LinkedList 是一个基于双向链表实现的集合类,经常被拿来和 ArrayList 做比较。
不过,我们在项目中一般是不会使用到 LinkedList 的,需要用到 LinkedList 的场景几乎都可以使用 ArrayList 来代替,并且,性能通常会更好!就连 LinkedList 的作者约书亚 · 布洛克(Josh Bloch)自己都说从来不会使用 LinkedList 。
另外,不要下意识地认为 LinkedList 作为链表就最适合元素增删的场景。我在上面也说了,LinkedList 仅仅在头尾插入或者删除元素的时候时间复杂度近似 O(1),其他情况增删元素的平均时间复杂度都是 O(n) 。
LinkedList 插入和删除元素的时间复杂度?
头部插入/删除:只需要修改头结点的指针即可完成插入/删除操作,因此时间复杂度为 O(1)。
尾部插入/删除:只需要修改尾结点的指针即可完成插入/删除操作,因此时间复杂度为 O(1)。
指定位置插入/删除:需要先移动到指定位置,再修改指定节点的指针完成插入 ...
ArrayList 源码分析
ArrayList 简介ArrayList 的底层是数组队列,相当于动态数组。与 Java 中的数组相比,它的容量能动态增长。在添加大量元素前,应用程序可以使用ensureCapacity操作来增加 ArrayList 实例的容量。这可以减少递增式再分配的数量。
ArrayList 继承于 AbstractList ,实现了 List, RandomAccess, Cloneable, java.io.Serializable 这些接口。
12345public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable{ }
List : 表明它是一个列表,支持添加、删除、查找等操作,并且可以通过下标进行访问。
RandomAccess :这是一个标志接口,表明实现这个接口的 List 集合是支持 快速随机访问 的。在 ArrayList 中,我们即可以 ...
进程的同步与互斥、常见的同步问题
基本概念
临界资源:一次仅允许一个进程使用的共享资源,也就是互斥资源
临界区:程序中访问临界资源的那段代码,也称危险区、敏感区
互斥:多个程序片段,同一时刻仅有一个能进入临界区
同步:若干程序片断运行必须严格按照规定的某种先后次序来运行。同步是一种更复杂的互斥:互斥不会限制程序对资源的访问顺序,即访问是无序的;而同步必须要按照某种次序来运行
临界区管理原则
任何两个进程不能同时处于其临界区
不应对 CPU 的速度和数量作任何假设
临界区外运行的进程不得阻塞其他进程
不得使进程无限等待进入临界区
当我们实现一个锁的时候,需要满足上述 4 个条件,才是一个正确的锁。
信号量和 P / V 操作信号量是一种特殊的变量,对它的操作都是原子的。对信号量的操作分为 down 和 up,分别对应 P 操作和 V 操作。P、V 来自于荷兰语:Probeer (try)、Verhoog (increment)。V 操作会增加信号量 S 的数值,P 操作会减少它。
执行 down 操作时,如果信号量值为 0,会使这个进程睡眠,否则,将信号量减 1
执行 up 操作时,如果这个信号量上有正在 ...










