Java的AQS框架设计原理

Java 的 AQS(AbstractQueuedSynchronizer) 是并发包(java.util.concurrent.locks)的核心框架,为构建锁和同步器提供了底层支持。以下是其核心原理和实现机制的深度解析:


一、AQS 核心设计思想

  1. 模板方法模式
    AQS 是一个抽象类,定义了同步器的骨架(如获取/释放资源的流程),具体实现由子类完成(如 ReentrantLockSemaphore)。

  2. CLH 变种队列
    通过 双向链表 实现的等待队列(FIFO),存储被阻塞的线程。

  3. 状态管理
    使用 volatile int state 表示共享资源状态(如锁的重入次数、信号量的许可数)。

阅读全文

Java的JUC并发库及其应用场景

Java 的 JUC(java.util.concurrent) 包是 Java 并发编程的核心工具集,提供了高性能、线程安全的并发类。以下是主要 JUC 类及其应用场景的详细分类解析:


一、锁与同步工具

1. ReentrantLock

  • 特点:可重入、支持公平/非公平锁、可中断、超时尝试。
  • 应用场景
    • 替代 synchronized 实现更灵活的锁控制。
    • 需要尝试获取锁或可中断锁的场景(如死锁恢复)。
  • 示例
    1
    2
    3
    4
    5
    6
    7
    ReentrantLock lock = new ReentrantLock();
    lock.lock();
    try {
    // 临界区代码
    } finally {
    lock.unlock();
    }
阅读全文

Redis底层数据结构

1. 类型与编码

1.1 对象类型

对象类型 类型常量 TYPE命令的输出
String REDIS_STRING “string”
List REDIS_LIST “list”
Hash REDIS_HASH “hash”
Set REDIS_SET “set”
Sorted Set REDIS_ZSET “zset”

1.2 对象编码

编码常量 底层数据结构 TYPE命令的输出
REDIS_ENCODING_INT long 类型的整数 “int”
REDIS_ENCODING_EMBSTR embstr 编码的简单动态字符串 “embstr”
REDIS_ENCODING_RAW 简单动态字符串 “raw”
REDIS_ENCODING_HT 字典 “hashtable”
REDIS_ENCODING_LINKEDLIST 双端链表 “linkedlist”
REDIS_ENCODING_ZIPLIST 压缩列表 “ziplist”
REDIS_ENCODING_QUICKLIST 快速链表 “quicklist”
REDIS_ENCODING_INTSET 整数集合 “intset”
REDIS_ENCODING_SKIPLIST 跳跃表和字典 “skiplist”
阅读全文

Redis主从复制Docker命令

1. 主节点

启动主节点:

1
$ docker run -d --name master --rm redis redis-server

查看启动日志:

1
$ docker logs master

连接docker开启redis客户端:

1
$ docker exec -it master redis-cli
阅读全文

Redis实现分布式锁Lua脚本

1. 简单锁

采用键值对存储,键是锁的标识,值是全局唯一值(如uuid)。

1.1 获取锁

1
2
3
4
5
6
7
8
9
10
11
12
13
14
-- lua in redis

local key = KEYS[1] -- 锁标识
local value = ARGV[1] -- 全局唯一值
local ttl = tonumber(ARGV[2]) or 0 -- 过期时间,默认不过期

if (redis.call('setnx', key, value) == 1) then
if (ttl > 0) then
redis.call('expire', key, ttl)
end
return 1
end

return 0

1.2. 释放锁

1
2
3
4
5
6
7
8
9
10
11
-- lua in redis

local key = KEYS[1] -- 锁标识
local value = ARGV[1] -- 全局唯一值

if (redis.call('get', key) == value) then
redis.call('del', key)
return 1
end

return 0
阅读全文

Redis实现限流器Lua脚本

1. 算法原理

系统以恒定的速率产生令牌,然后把令牌放到令牌桶中,令牌桶有一个容量,当令牌桶满了的时候,再向其中放入的令牌会被丢弃;当想要处理一个请求的时候,需要从令牌桶中取出一个令牌,如果此时令牌桶中没有令牌,则拒绝该请求。

2. 数据结构

采用Hash结构存储,字段定义如下:

名称 含义
capacity 令牌桶容量
remain 剩余令牌数
period 时间窗口大小(秒)
quota 时间窗口内的限额
timestamp 生成令牌的时间戳(秒)
阅读全文

基于Redis位图实现用户签到功能

1. 场景需求

适用场景如签到送积分、签到领取奖励等,大致需求如下:

  • 签到1天送1积分,连续签到2天送2积分,3天送3积分,3天以上均送3积分等。
  • 如果连续签到中断,则重置计数,每月初重置计数。
  • 当月签到满3天领取奖励1,满5天领取奖励2,满7天领取奖励3……等等。
  • 显示用户某个月的签到次数和首次签到时间。
  • 在日历控件上展示用户每月签到情况,可以切换年月显示……等等。

2. 设计思路

对于用户签到数据,如果每条数据都用K/V的方式存储,当用户量大的时候内存开销是非常大的。而位图(BitMap)是由一组bit位组成的,每个bit位对应0和1两个状态,虽然内部还是采用String类型存储,但Redis提供了一些指令用于直接操作位图,可以把它看作是一个bit数组,数组的下标就是偏移量。它的优点是内存开销小、效率高且操作简单,很适合用于签到这类场景。

阅读全文

Dubbo的工作原理

Dubbo 是阿里巴巴开源的一款高性能、轻量级的 Java RPC 框架,主要用于分布式服务之间的远程调用。它提供了服务治理、负载均衡、容错机制等功能,广泛应用于微服务架构中。以下是 Dubbo 的工作原理及其核心机制的详细解析:


1. Dubbo 的核心概念

在理解 Dubbo 的工作原理之前,需要先了解其核心概念:

(1) 服务提供者(Provider)

  • 服务的实现方,负责提供服务接口的具体实现。
  • 服务提供者将服务注册到注册中心。

(2) 服务消费者(Consumer)

  • 服务的调用方,负责调用服务提供者提供的服务。
  • 服务消费者从注册中心订阅服务。
阅读全文

HEXO搭建个人博客

1. 使用NPM安装HEXO
1
npm install -g hexo
2. 初始化HEXO目录
1
hexo init
3. 生成静态页面
1
hexo generate 或 hexo g
4. 启动HEXO服务
1
hexo server
阅读全文