自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(71)
  • 收藏
  • 关注

原创 【Java 并发】AbstractQueuedSynchronizer 中的 Condition

任何一个 Java 对象都天然继承于 Object 类, 在线程间实现通信的往往会应用到 Object 的几个方法, 比如 wait(), wait(long timeout), wait(long timeout, int nanos) 与 notify(), notifyAll()几个方法实现等待 / 通知机制。同样的, 在 Java Lock 体系下也有同样的方法实现等待/通知机制。从整体上来看。

2024-03-15 10:44:46 833

原创 【MySQL】事务

事务是数据库管理系统 (DBMS) 执行过程中的一个逻辑单位, 由一个有限的数据库操作序列构成, 这些操作要么都做, 要么都不做, 是一个不可分割的工作单位。事务是数据库最小的工作单元, 是不可以再分的, 可能包含了一个或者一系列的 DML 语句。

2024-03-15 10:43:43 865

原创 【MySQL】事务

事务是数据库管理系统 (DBMS) 执行过程中的一个逻辑单位, 由一个有限的数据库操作序列构成, 这些操作要么都做, 要么都不做, 是一个不可分割的工作单位。事务是数据库最小的工作单元, 是不可以再分的, 可能包含了一个或者一系列的 DML 语句。

2024-03-15 10:42:17 945

原创 【MySQL】锁信息

MySQL 锁(Lock)是数据库管理系统用于管理并发访问的一种机制。在多用户同时访问数据库的环境下,可能会出现多个事务同时对相同的数据进行读取或写入操作,为了保证数据的一致性和完整性,需要使用锁来控制对数据的访问。在并发环境下,当多个事务试图同时访问相同的数据时,锁可以确保只有一个事务能够成功地获取对数据的访问权限,其他事务需要等待或被阻塞,直到获得相应的锁为止。锁的主要作用是防止多个事务同时对同一数据进行不一致的修改,从而避免数据的丢失、错误或混乱。

2024-03-14 20:06:30 1533

原创 【Java 并发】AbstractQueuedSynchronizer

在同步组件的实现中, AQS 是核心部分, 同步组件的实现者通过使用 AQS 提供的模板方法实现同步组件语义。AQS 则实现了对同步状态的管理, 以及对阻塞线程进行排队, 等待通知等一些底层的实现处理。

2024-03-14 20:01:33 413

原创 【Java 并发】Semaphore

Java 中 的 Semaphore (信号量) 是多线程编程中一种重要的同步工具, 用于控制对共享资源的访问。通过 Semaphore, 我们可以限制同时访问共享资源的线程数量, 有效地管理并发访问, 确保程序在多线程环境下的稳定性和效率。在一些资源有限制场景下, Semaphore 是特别合适的, 比如流量控制, 数据库连接池等。

2024-03-11 20:06:32 474

原创 【Java 并发】AbstractQueuedSynchronizer (AQS) 初识

在源码中, 对 AQS 的解释 (可以查看 AbstractQueuedSynchronizer 的类注释)提供了一个框架, 用于实现依赖于先进先出 (FIFO) 的等待队列的阻塞锁和相关的同步器 (例如: 信号量, 事件等)。这个类是被设计用来作为一个有用的基础, 为大部分的依靠一个单独的原子变量来表示状态的同步器。AQS (同步器) 是用来构建锁和其他同步组件的基础框架, 它的实现主要依赖一个int 成员变量来表示同步状态以及通过一个FIFO 队列构成等待队列。

2024-03-11 19:21:26 820

原创 【Java JVM】常用参数

设置为 4,则两个 Survivor 区与一个 Eden 区的比值为 1:1:4,一个 Survivor 区占整个年轻代的 1/6, -XX:SurvivorRatio=4。-XX:NewRatio: 设置年轻代和年老代的比值 (除去持久代), 设置为 4,则年轻代与年老代所占比值为 1:4,年轻代占整个堆栈的 1/5, -XX:NewRatio=4。-XX:MaxPermSize: 设置持久代大小, JDK8 后废弃了, 通过元空间进行配置, -XX:MaxPermSize=16m。

2024-03-07 10:03:47 356

原创 【Java JVM】方法调用

方法调用并不等同于方法中的代码被执行, 方法调用阶段唯一的任务就是确定被调用方法的版本 (即调用哪一个方法), 暂时还未涉及方法内部的具体运行过程。Class 文件的编译过程中不包含传统程序语言编译的连接步骤, 一切方法调用在 Class 文件里面存储的都只是符号引用, 而不是方法在实际运行时内存布局中的入口地址 (也就是之前说的直接引用), 这个特性给 Java 带来了更强大的动态扩展能力, 但也使得 Java 方法调用过程变得相对复杂, 某些调用需要在类加。

2024-03-07 10:03:20 915

原创 【Java JVM】Class 文件的加载

Java 虚拟机把描述类的数据从 Class 文件加载到内存, 并对数据进行校验, 转换解析和初始化, 最终形成可以被虚拟机直接使用的 Java 类型,这个过程被称作虚拟机的。与那些在编译时需要进行连接的语言不同, 在 Java 语言里面, 类的加载, 连接和初始化过程都是在程序运行期间完成的, 这种策略让 Java 语言进行提前编译会面临额外的困难,

2024-03-06 16:37:05 1020

原创 【Java JVM】Class 文件

类或接口的符号引用表 CONSTANT_Class_info 的内容如下。

2024-03-06 16:36:25 981

原创 【Java JVM】垃圾回收

在 64 位系统中, 理论可以访问的内存搞定 16EB (2 的 64 次幂)。为了实现 “Brooks Pointer”, Shennandoah 在原有的写屏障内加入了额外的转发处理, 还使用了读屏障, 代码里面对象的读取斌率的对对象的写入频率高很多的操作, 大量的读屏障开销会是一个性能问题。(2) 转发指针的作用, 当对象拥有一份新的副本时, 只需要修改一处指针的值, 即旧对象上转发指针的引用位置, 使其执行新的对象, 就可以将所有对该对象的访问转发到新的副本上。

2024-03-05 20:55:46 4249

原创 【Java JVM】对象回收判断

Java 对象回收判断是程序设计中至关重要的一环。在面向对象的编程中, 合理的对象回收策略直接影响着程序的性能和内存利用效率。因此, 深入了解和准确判断 Java 对象的回收时机, 不仅可以优化程序的运行性能, 还能有效避免内存泄漏和资源浪费。本文将简单的分析一下 JVM 中对象回收的判断机制, 了解一下整体的对象回收过程。

2024-03-05 20:55:02 1514

原创 【Java JVM】栈帧

执行引擎是 Java 虚拟机核心的组成部分之一。在《Java虚拟机规范》中制定了 Java 虚拟机字节码执行引擎的概念模型,这个概念模型成为各大发行商的 Java 虚拟机执行引擎的统一外观 (Facade)。不同的虚拟机的实现中, 通常会有而这一个的过程, 落实到 HotSpot 的实现就是。下面会对做一个简单的介绍。

2024-01-14 20:12:58 1239

原创 【Redis】AOF 源码

在上篇, 我们已经从使用 / 机制 / AOF 过程中涉及的辅助功能等方面简单了解了 Redis AOF。这篇将从源码的形式, 进行深入的了解。

2024-01-14 19:56:20 1107

原创 【Java 集合】ThreadLocal

在多线程编程中,我们经常面临共享数据的问题,而这可能引发一系列并发性和线程安全性的挑战。Java 提供了许多机制来处理这些问题,比如控制并发的各种锁, 控制线程串行地修改资源, 避免线程安全, 或者通过关键字 volatile 修饰变量, 保证可见性等。而在解决并发共享的方式中, 还有一种方式, 那么就是线程隔离, 每个线程各自维护资源的副本, 从而避免了共享资源的竞争。

2023-12-25 21:46:12 1057

原创 【Java JVM】Java 实例对象的访问定位

Java 程序会通过栈上的 reference 数据来操作堆上的具体对象。但是 reference 类型在《Java虚拟机规范》里面只规定了它是一个指向对象的引用, 并没有定义这个引用应该通过什么方式去定位, 访问到堆中对象的具体位置,所以对象访问方式也是由虚拟机实现而定的,主流的访问方式主要有使用和两种。

2023-12-24 23:56:20 656

原创 【Java 并发】Exchanger

Exchanger 是一个用于线程间协作的工具类, 用于两个线程间能够交换。它提供了一个交换的同步点, 在这个同步点两个线程能够交换数据。具体交换数据是通过 exchange 方法来实现的, 如果一个线程先执行 exchange 方法, 那么它会阻塞等待另一个线程也执行 exchange 方法, 这个时候两个线程就都达到了同步点, 两个线程就可以交换数据。

2023-12-24 23:54:43 914

原创 【Java 并发】ThreadPool

从 Java 线程池 Executor 框架体系可以看出 ThreadPoolExecutor 是线程池的定义。// 自定义线程工厂类@Override// 创建线程池// 自定义 Runable 任务// 提交任务// 关闭线程池Worker 是 ThreadPoolExecutor 的内部类, 继承了 AbstractQueuedSynchronizer (AQS) 和 实现了 Runnable 2 个接口。

2023-12-22 22:13:49 998

原创 【Java JMM】编译和优化

语法分析, 根据标记序列构造抽象语法树, 主要由 com.sun.tools.javac.parser.Parser, 产生的抽象树为 com.sun.tools.javac.tree.JCTree。字节码生成, 由 com.sun.tools.javac.jvm.Gen 完成, 把前面各个步骤生成的信息 (语法树, 符号表) 转为字节码, 还会进行少了代码的添加和转换,当然最简单的方式就是打开一包编译器, 顺便建立一个 Java 项目, 搜索 com.sun.tools.javac.Main 就可以了。

2023-12-22 22:09:56 950

原创 【Java 并发】CyclicBarrier 介绍

在多线程编程中, 协调和同步线程的执行是至关重要的。Java 提供了许多并发工具来帮助开发人员有效地管理多线程应用程序。其中之一是 CyclicBarrier, 它是一个强大的同步辅助类, 可用于在多个线程之间创建同步点, 以便它们可以在同一时间点协调执行某个任务。CyclicBarrier 和 CountDownLatch 一样具有等待计数的功能, 但是相比于 CountDownLatch 功能更加强大。其本身具备了以下特点。

2023-12-21 22:19:33 366

原创 【Java 集合】LinkedBlockingDeque

我们知道 LinkedBlockingDeque 的底层实现结构就是一个链表, 而链表绕不开的一个概念就是节点, 所以我们先来看一下 LinkedBlockingDeque 的节点定义。/*** 节点类, 用于存储数据*/// 存储的内容E item;// 上一个节点的指针// 下一个节点的指针item = x;上面的 Node 就是队列中的节点了, 声明的属性item: 存储的内容prev: 上一个节点的指针next: 下一个节点指针。

2023-12-21 21:55:13 932

原创 【Java 集合】ConcurrentHashMap (JDK 1.8 版本)

Map 一种存储键值对 (key-value) 的数据结构, 可以通过 key 快速地定位到需要的 value, 在 Java 中是一个使用频率很高的一个数据结构。一般情况下, 我们都是可以直接使用它的实现类 HashMap 就能满足需求了。但是 HashMap 在多线程情况, 并不是一个线程安全的类。使用在 Java 体系中古老的 Hashtable 作为替代, 该类基本上所有的方法都采用 synchronized 进行线程安全的控制, 虽然保证了线程安全, 但是牺牲了很大的性能。

2023-12-20 15:11:46 1807

原创 【Java JVM】JVM 分析工具

在 $JAVA_HOME/bin 的目录下, 存在着许多小工具, 除了编译和运行 Java 程序外, 打包, 部署, 签名, 调试, 监控, 运维等各种场景都可能会用到它们。

2023-12-20 15:08:29 1109

原创 【Java 并发】CountDownLatch 介绍

的核心特点在于它是一种倒计数器, 初始值设定为某个正整数。在多线程任务中, 当一个线程完成了一定的操作, 可通过调用 countDown() 方法来使计数器减 1, 而其他线程可通过 await() 方法等待计数器变为零。一旦计数器变为零, 等待的线程将被唤醒继续执行。为了能够理解 CountDownLatch, 举一个很通俗的例子。运动员进行跑步比赛时, 假设有 6 名运动员参与比赛, 裁判员在终点会为这 6 名运动员分别计时, 可以想象每当一个运动员到达终点的时候,

2023-12-19 23:20:34 871

原创 【Java 集合】LinkedBlockingQueue

我们知道 LinkedBlockingQueue 的底层实现结构就是一个链表, 而链表绕不开的一个概念就是节点, 所以我们先来看一下 LinkedBlockingQueue 的节点定义。// 链表节点类, 数据的主要存储地方// 节点的数据E item;// 下一个节点item = x;通过节点 Node 的定义中就一个数据域和一个指向下一个节点的指针, 明确 LinkedBlockingQueue 就是一个单向链表。

2023-12-19 23:19:21 847

原创 【Java 集合】ArrayBlockingQueue

它是 BlockingQueue 接口的一种实现,通过固定大小的数组来存储元素,同时借助 ReentrantLock 和 ReentrantLock 的 Condition 提供了阻塞操作,使得在队列已满或为空时,线程能够安全地等待。内部借助头尾 2 个指针的移动达到一种循环数组的效果, 避免了整个元素删除时, 数组需要将后面的元素迁移的操作。

2023-12-18 22:27:07 842

原创 【Java 集合】BlockingQueue 简介

在 Java 中容器主要有 2 个大类 Collection 和 Map, 其中 Collection 主用用于数据的直接存储 (Map 则是一种键值对的存储方式, 除了要存储的数据外, 还需要有一个 key 和数据建立一个映射关系)。Collection 使用的最多的大概就是 List, Set 和 Queue。而在日常的开发中, 会根据不同数据的特性, 比如是否可重复, 是否需要有序等条件选择不同的集合, 同时还会考虑其他的因素, 比如线程是否安全。

2023-12-18 22:25:03 814

原创 【Redis】AOF 基础

因为 Redis AOF 的实现有些绕, 就分成 2 篇进行分析, 本篇主要是介绍一下 AOF 的一些特性和依赖的其他函数的逻辑,为下一篇 (Redis AOF 源码) 源码分析做一些铺垫。AOF 全称: Append Only File, 是 Redis 提供了一种数据保存模式, Redis 默认不开启。AOF 采用日志的形式来记录每个写操作, 并追加到文件。开启后, 执行更改 Redis 数据的命令时, 就会把命令写入到 AOF 文件中。

2023-12-17 16:20:24 1800

原创 【Java 并发】三大特性

synchronized 具有: 原子性, 有序性, 可见性。volatile 具有:有序性,可见性。synchronized 是否保证有序性呢?从上面的双重检测看起来, synchronized 貌似不保证有序性, 但是 synchronized 还是保证有序性的, 只是和 volatile 的有序性不一样。volatile 关键字禁止 JVM 编译器和处理器对其进行重排序, 而 synchronized 保证的有序性是只有单线程可以获取锁, 串行地执行同步代码。

2023-12-17 14:21:18 796

原创 【Java JVM】实例对象的创建

当我们涉及 Java 编程时,对象的创建是一个基础而关键的概念。在 Java 中,一切皆为对象,而对象的创建方式直接影响代码的结构和性能。本博客将探讨一下 Java 实例对象的创建过程。

2023-12-17 13:16:32 732

原创 【Java JVM】实例对象内存布局

当 Java 应用启动后, 基本就是在不断的创建对象, 回收对象的过程中。而这些创建的对象基本都是存放在应用的堆 (heap) 中, 但是这些对象在堆中又是什么样子的呢?在这篇文章中, 我们分析一下 Java JVM 中实例对象的内存布局。在 HotSpot 虚拟机里, 对象在堆内存中的存储布局可以划分为三个部分: 对象头 (Object Header), 实例数据 (Instance Data) 和对齐填充 (Padding)。

2023-12-16 14:01:27 950

原创 【Java JVM】运行时数据区

JVM 在执行 Java 程序的过程中会把它管理的内存分为若干个不同的数据区域, 这些区域有着各自的用途。根据《Java虚拟机规范》中规定, JVM 所管理的内存大致包括以下几个运行时数据区域, 如图所示:这个运行时数据区被分为了 5 大块其中: 绿色部分是各个线程之间独享的部分, 而蓝色部分是所有线程共享的区域。

2023-12-16 00:18:38 963

原创 【Java 集合】ConcurrentLinkedQueue

ConcurrentLinkedQueue 是 Java 中的一个并发队列实现, 位于 java.util.concurrent 包下。它提供了一个基于链表实现的无界线程安全队列, 采用非阻塞算法实现并发操作。无界队列: ConcurrentLinkedQueue 不限制队列的大小, 可以动态地增长非阻塞算法: 内部实现采用了非阻塞算法, 避免了传统锁的性能开销, 提高了并发性能。

2023-12-15 22:05:29 1197

原创 【MySQL】InooDB 索引实现

维基百科对数据库索引的定义:数据库索引是数据库管理系统(DBMS)中的一个排序数据结构, 以协助快速查询和更新数据库表中的数据。MongoDB对索引的定义:索引是一种特殊的数据结构, 以有序和便于遍历的形式存储数据集合中特定字段或一组字段的值。索引条目的排序支持有效的相等匹配和基于范围的查询操作。理解:数据库表中的数据以文件的形式存放在磁盘上, 每一行数据都有其磁盘地址。如果没有索引, 要从表中检索一条数据, 只能依次遍历整张表的数据, 直到找到这条数据。

2023-12-15 22:04:15 1150

原创 【生产问题记录】一次 CPU 占用率过高的问题排查 (不断创建线程和线程上下文频繁切换)

至此, 整个 CPU 占用率高的排查过程就结束了, 后面再对整个过程做个总结通过比较线程栈的信息, 定位到了 @Async 注解的实现中, 通过不断创建线程执行任务的, 这个行为会导致 CPU 消耗资源在重量级对象 Thread 的创建和消毁中第二次通过观察线程栈信息, 定位到大量的线程阻塞在日志输出处, 执行的任务也是在输出日志, 猜测是频繁的日志打印, 导致线程上下文切换, 通过减少日志打印进行验证结论。

2023-12-10 19:12:20 1043

原创 【Java 并发】JMM 的一些理解

如果一个操作 Happens-Before 另一个操作, 那么第一个操作的执行结果将对第二个操作可见, 而且第一个操作的执行顺序排在第二个操作之前两个操作之间存在 Happens-Before 关系, 并不意味着 Java 平台的具体实现必须要按照 Happens-Before 关系指定的顺序来执行。如果重排序之后的执行结果, 与按 Happens-Before 关系来执行的结果一致, 那么这种重排序并不非法 (也就是说, JMM 允许这种重排序)第一条是 JMM 对程序员的保证。

2023-12-10 19:03:29 467

原创 【Redis】RDB 实现

备注: 下面二进制之间每 8 位就手动空了一个空格, 只是为了方便理解, 真正写入文件时, 中间是不会有空格的在实际中, Reids 会将数据以二进制的形式写入到文件中, 格式可能如下在开始介绍 Redis 自定义的整数规则前, 先看一个 Redis将数据写入文件的伪代码// 1. 数据的长度在 11 个字节以内 (int 最大值, 21 亿, 10 位数)// 尝试转为 int 写入return;// 2. 开启了 LZF 压缩算法, 同时数据长度大于 20 个字节return;

2023-12-02 20:18:33 1205

原创 【Java 基础】Throwable

如图展示了 Java 整个异常体系的关系。Throwable 的 Java 异常体系的基类, 他的直接子类有 Error 和 Exception 2 个。

2023-12-02 20:06:14 431

原创 【Java 集合】HashSet

HashSet 是一个基于 HashMap 实现的无序列表。它不保证数据存储的顺序, 但是可以保证存储的数据是唯一不重复的, 同时支持存储 null。如果再了解 HashMap 后, HashSet 是几个 Collection 实现中最容易理解的集合, 因为 HashSet 的所有操作都是借助于 HashMap 实现的。

2023-11-28 22:59:19 430

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除