redisson

Spring集成Redisson配置RedissonAutoConfiguration初始化源码解析 Redisson数据源初始化源码 ,当前版本3.13.6 /** * Copyright (c) 2013-2020 Nikita Koksharov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License 阅读详情

lettuce

redistemplate是springboot2.X后面,由lettuce具体实现,1.x的是jedis,redisson是redis的分布式客户端

Lettuce 是一个 ​基于 Netty 的高性能、线程安全的 Java Redis 客户端,专为高并发和异步场景设计。以下是其核心要点
​异步与非阻塞:基于 Netty 实现,支持异步和响应式编程(如 Reactive Streams)。
​线程安全:单个连接实例可被多线程共享,无需连接池。
​协议支持:完整支持 Redis 5/6/7 的协议(RESP2/RESP3)、集群、哨兵、管道、事务等。
​长连接:支持连接自动重连和心跳保活,适合长时间运行的分布式服务。

redisson

<dependency>
  <groupId>org.redisson</groupId>
  <artifactId>redisson</artifactId>
  <version>3.15.4</version>
</dependenc

命令

  • 1
    在这里插入图片描述

redisson

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

1. 使用官网git

link

什么场景需要用到RScoredSortedSet,举例说明

  1. 实时排行榜:在游戏、竞赛或社交应用中,需要实时地根据分数来排名用户或团队。ScoredSortedSet可以将用户的得分作为分数,并将用户对象添加到集合中。通过调用方法如reverseRange,可以轻松地获取排行榜上的前几名。

  2. 时间线:类似于社交媒体平台的时间线,可以使用ScoredSortedSet按照发布时间对帖子进行排序。每个帖子可以关联一个时间戳作为分数,通过添加帖子对象到集合中并调用range方法,可以按照时间顺序获取帖子列表。

  3. 任务调度:当需要按优先级执行任务时,可以使用ScoredSortedSet来存储任务对象,并将任务的优先级作为分数。通过调用range方法,可以按优先级顺序获取要执行的任务列表。

  4. 范围查询:ScoredSortedSet还支持范围查询操作,可以根据指定的分数范围来获取成员列表。例如,在电子商务应用程序中,可以使用ScoredSortedSet来存储商品,并将商品的价格作为分数。这样,可以方便地根据指定价格范围来获取商品列表。

aip

  1. add(double score, V object): 将成员对象添加到集合中,并为其指定分数。
  2. removeRangeByScore(double startScore, boolean startIncluded, double endScore, boolean endIncluded): 删除给定范围内的成员。可以选择是否包含起始和结束分数。
  3. score(V object): 获取指定成员的分数。
  4. rank(V object): 获取指定成员在集合中的排名(从0开始)。
  5. count(double startScore, boolean startIncluded, double endScore, boolean endIncluded): 计算给定范围内成员的数量。可以选择是否包含起始和结束分数。
  6. range(double startScore, boolean startIncluded, double endScore, boolean endIncluded): 返回给定范围内的成员列表。可以选择是否包含起始和结束分数。
  7. reverseRank(V object): 获取指定成员在集合中的逆序排名(从0开始)。
  8. reverseRange(int startIndex, int endIndex): 返回指定范围内的成员列表,按逆序排列。

RScoredSortedSet原理

RScoredSortedSet 通过 Redis 原生的 Sorted Set 实现分布式有序集合,借助跳跃表和哈希表的高效性,结合 Lua 脚本的原子性,提供了高性能的排序、范围查询

3. Redission RAtomicLong

今天有多少订单产生,统计大屏;

有多少柜机在线;

RAtomicLong本身可以满足单次操作的原子性需求,

简单计数场景
直接使用RAtomicLong的原子方法(如incrementAndGet()),无需额外处理。

高并发场景优化
本地预生成ID缓冲池(减少Redis访问)
冷热数据分离(高频操作用RAtomicLong,低频数据用数据库)

4. RScoredSortedSet 实现LFU

 public static void main(String[] args) {
        // 创建 Redisson 配置
        Config config = new Config();
        config.useSingleServer().setAddress("redis://127.0.0.1:6379");

        // 创建 Redisson 客户端
        RedissonClient redisson = Redisson.create(config);

        // 获取有序集合
        RScoredSortedSet<String> sortedSet = redisson.getScoredSortedSet("mySortedSet");

        // 插入数据的函数
        insertData(sortedSet, "data1");
        insertData(sortedSet, "data2");
        insertData(sortedSet, "data1"); // "data1" already exists, score should be incremented
        insertData(sortedSet, "data3");
        insertData(sortedSet, "data4");
        insertData(sortedSet, "data5");
        insertData(sortedSet, "data5");
        insertData(sortedSet, "data6");
        insertData(sortedSet, "data7");
        insertData(sortedSet, "data8");
        insertData(sortedSet, "data9");
        insertData(sortedSet, "data10");
        insertData(sortedSet, "data11");
        insertData(sortedSet, "data12");

        // 打印集合内容
        System.out.println("111");
        final val scoredEntries = sortedSet.entryRangeReversed(0, -1);
        final val collect = scoredEntries.stream().map(ScoredEntry::getValue).collect(Collectors.toList());
        System.out.println(JSONObject.toJSONString(collect));


        // 获取按分数由高到低排序的所有数据

        // 打印集合内容
        for (ScoredEntry<String> entry : scoredEntries) {

            System.out.println("Data: " + entry.getValue() + ", Score: " + entry.getScore());
        }

        // 关闭 Redisson 客户端
        redisson.shutdown();
    }

    public static void insertData(RScoredSortedSet<String> sortedSet, String data) {
        Double currentScore = sortedSet.getScore(data);
        if (currentScore != null) {
            // 数据已经存在,分数加一
            sortedSet.addScore(data, 60*60*24);
        } else {
            // 数据不存在,插入新数据
            if (sortedSet.size() < 10) {
                sortedSet.add(System.currentTimeMillis()/100000, data);
            } else {
                // 插入新数据
                sortedSet.add(System.currentTimeMillis()/100000, data);

                // 获取分数最低的元素集合(有多个分数相同的情况)
                Collection<String> lowestScoreElements = sortedSet.valueRange(0, 0);

                // 找到插入时间最早的元素
                String earliestElement = null;
                long earliestTimestamp = Long.MAX_VALUE;
                for (String element : lowestScoreElements) {
                    Double score = sortedSet.getScore(element);
                    if (score != null && score < earliestTimestamp) {
                        earliestTimestamp = score.longValue();
                        earliestElement = element;
                    }
                }

                // 删除分数最低且插入时间最早的元素
                if (earliestElement != null) {
                    sortedSet.remove(earliestElement);
                }
            }
        }
    }

5. 分布式锁

one 原理

1. 锁的存储结构

Redisson 的分布式锁通过 Redis 的 Hash 结构 存储锁信息,键的格式为 锁名称(例如 myLock),字段(field)为客户端唯一标识(UUID + 线程ID),值为锁的重入次数(计数器)。例如:

HGETALL myLock
1) "b983c153-8b6a-4a7a-8e2a-3f0a7d8f3c7b:1"  # 客户端ID:线程ID
2) "3"  # 重入次数

在这里插入图片描述

2. 加锁过程(lock())

当调用 lock() 方法时,Redisson 执行以下流程:

步骤 1:尝试加锁

使用 Lua 脚本(保证原子性)尝试在 Redis 中创建锁:

  • 如果锁不存在(exists == 0),则通过 hset 设置锁的 Hash 字段,初始化重入次数为 1,并设置过期时间(默认 30 秒)。
  • 如果锁已存在且是当前线程持有(可重入),则重入次数加 1,并更新过期时间。
  • 如果锁被其他线程占用,则通过 Redis 的发布订阅机制订阅锁释放事件,进入循环等待。
-- Lua 脚本伪代码
if (redis.call('exists', KEYS[1]) == 0) then
    redis.call('hset', KEYS[1], ARGV[2], 1);
    redis.call('pexpire', KEYS[1], ARGV[1]);
    return nil;
end;
if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then
    redis.call('hincrby', KEYS[1], ARGV[2], 1);
    redis.call('pexpire', KEYS[1], ARGV[1]);
    return nil;
end;
return redis.call('pttl', KEYS[1]);
步骤 2:锁续期(Watchdog 机制)

如果锁获取成功,Redisson 会启动一个后台线程(看门狗),每隔 10 秒 检查锁是否仍被持有。如果是,则自动将锁的过期时间重置为 30 秒,防止业务逻辑未执行完锁被自动释放。


3. 解锁过程(unlock())

调用 unlock() 时,Redisson 通过 Lua 脚本减少重入次数,直到计数器归零后删除锁:

-- Lua 脚本伪代码
if (redis.call('hexists', KEYS[1], ARGV[3]) == 0) then
    return nil;
end;
local counter = redis.call('hincrby', KEYS[1], ARGV[3], -1);
if (counter > 0) then
    redis.call('pexpire', KEYS[1], ARGV[2]);
    return 0;
else
    redis.call('del', KEYS[1]);
    redis.call('publish', KEYS[2], ARGV[1]);
    return 1;
end;
  • 每次解锁会将重入次数减 1,直到计数器为 0 时删除锁。
  • 通过 Redis 的发布订阅机制通知等待线程锁已释放。

4. 关键特性

  1. 可重入性
    同一线程多次获取锁时,重入次数递增,避免死锁。

  2. 自动续期(Watchdog)
    防止因业务执行时间过长导致锁超时释放。

  3. 避免死锁
    锁默认 30 秒过期(即使未显式释放),结合 Watchdog 续期。

  4. 互斥性
    基于 Redis 的单线程特性,确保锁的互斥访问。


5. 高可用场景(RedLock)

在 Redis 集群模式下,Redisson 支持 RedLock 算法(多节点加锁),通过多个独立的 Redis 实例协同工作,提升分布式锁的可靠性。但 getLock 默认基于单节点实现,若需高可用需显式使用 RedissonRedLock。


总结

RedissonClient.getLock() 的底层实现结合了 Redis 的原子操作、Lua 脚本、发布订阅和看门狗机制,提供了一个高效、可靠的分布式锁,解决了传统 SETNX 命令的局限性(如不可重入、无自动续期等问题)。

模版代码

Lock lock = ...;
 if (lock.tryLock()) {
   try {
     // manipulate protected state
   } finally {
     lock.unlock();
   }
 } else {
   // perform alternative actions
 }

6. redission实现公平锁的实现原理

  1. 排队机制:
  • 当多个客户端尝试获取锁时,Redisson 会将它们放入一个队列中(这个队列存储在 Redis 里),按照请求的时间顺序排队。

  • 只有队列中的第一个客户端才能获得锁。

  1. 监听机制:
  • 每个客户端在尝试获取锁失败后,会订阅一个特定的频道(channel),以监听前一个释放锁的事件。

  • 当前一个客户端释放锁时,它会发布一个消息到该频道,通知下一个客户端来尝试获取锁。

  1. 超时与重试:
  • 客户端在等待锁的过程中会有一个超时时间,如果超时仍未获得锁,则放弃获取锁并移出队列。

  • 客户端可以设置等待锁的最长时间和锁的持有时间。

7. 再谈公平锁

Redisson 公平锁实现原理与最佳实践

Redisson 的公平锁(Fair Lock)是一种分布式锁实现,它按照请求锁的顺序来分配锁,确保所有等待锁的客户端按照先来先服务的原则获得锁资源。

公平锁的实现原理

Redisson 公平锁基于 Redis 的 Lua 脚本和发布/订阅机制实现,核心设计如下:

1. 排队机制

  • 使用 Redis 的 List 数据结构作为等待队列
  • 每个客户端尝试获取锁时,会生成唯一标识并加入队列尾部
  • 只有队列头部的客户端才能获得锁

2. 锁获取流程

是
是
否
否
是
否
是
客户端尝试获取锁
锁是否空闲?
检查是否为队列第一个
获取锁成功
加入等待队列
订阅锁释放消息
等待超时?
获取锁失败
收到锁释放通知

3. 关键组件

  • 等待队列:Redis List 存储等待客户端(键格式:redisson_lock_queue:{lockName})
  • 超时集合:Redis Sorted Set 跟踪客户端等待时间(键格式:redisson_lock_timeout:{lockName})
  • 订阅通道:Redis Pub/Sub 通知锁释放事件

公平锁的使用方式

基本用法

import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;

public class FairLockExample {
    
    private final RedissonClient redissonClient;
    
    public void performTaskWithFairLock() {
        RLock fairLock = redissonClient.getFairLock("myFairLock");
        
        try {
            // 尝试获取锁,最多等待10秒,锁持有时间30秒
            if (fairLock.tryLock(10, 30, TimeUnit.SECONDS)) {
                // 执行需要锁保护的代码
                executeCriticalSection();
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            if (fairLock.isLocked() && fairLock.isHeldByCurrentThread()) {
                fairLock.unlock();
            }
        }
    }
    
    private void executeCriticalSection() {
        // 关键业务逻辑
    }
}

最佳实践建议

  1. 合理设置等待时间

    // 根据业务场景设置合理的等待时间
    boolean acquired = fairLock.tryLock(15, 60, TimeUnit.SECONDS);
    
  2. 避免锁泄漏

    finally {
        // 确保只有持有锁的线程才能解锁
        if (fairLock.isHeldByCurrentThread()) {
            fairLock.unlock();
        }
    }
    
  3. 处理中断异常

    catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        // 执行清理操作或重试逻辑
    }
    

公平锁 vs 非公平锁

特性公平锁非公平锁
获取顺序先进先出(FIFO)随机竞争
性能较低(维护队列开销)较高
饥饿问题不会发生可能发生
实现复杂度较高较低
适用场景需要严格顺序执行的业务高并发、低延迟场景

fair and unfair

公平用的队列, 非公平用的发布订阅
Redisson的公平锁和非公平锁在锁释放通知机制上有重要区别。下面我将详细解释两种锁在锁释放时如何通知等待的客户端:

1. 公平锁(Fair Lock)的通知机制

公平锁使用队列机制保证获取锁的顺序(FIFO)。当锁释放时:

  • 仅通知队列中的第一个等待客户端(即等待时间最长的客户端)

  • 其他等待客户端不会收到通知,直到它们成为队列头部

锁持有者 Redis 客户端甲 (队首) 客户端乙 客户端丙 释放锁(del + publish) 发布锁释放消息(仅队首) 尝试获取锁 获取成功 锁持有者 Redis 客户端甲 (队首) 客户端乙 客户端丙

实现关键点:

  • 使用Redis的List结构作为等待队列(键:redisson_lock_queue:{lockName})

  • 每个客户端在队列中的位置固定

  • 锁释放时,Redis执行Lua脚本:

  1. 从队列头部取出第一个客户端

  2. 向该客户端的专属频道发布通知

2. 非公平锁(Non-fair Lock)的通知机制

非公平锁在锁释放时:

  • 向所有等待客户端广播锁释放消息

  • 所有收到通知的客户端会同时竞争锁

锁持有者 Redis 客户端甲 客户端乙 客户端丙 释放锁(del + publish) 发布锁释放消息(广播) 发布锁释放消息(广播) 发布锁释放消息(广播) 竞争获取锁 竞争获取锁 竞争获取锁 返回获取成功(随机) 锁持有者 Redis 客户端甲 客户端乙 客户端丙

最佳实践建议

  1. 需要严格顺序:使用公平锁(如订单处理、资源分配)

  2. 追求高吞吐:使用非公平锁(如库存扣减)

  3. 避免大量等待:

  • 设置合理的锁等待超时时间

  • 使用tryLock而非无限制的lock

  1. 监控等待队列长度:

RLock lock = redisson.getFairLock("fairLock");

// 获取等待线程数(Redisson 3.17+)

int waitCount = lock.getQueueSize();

结论

  • 公平锁:锁释放时只通知等待队列中的第一个客户端(甲),确保获取顺序。

  • 非公平锁:锁释放时向所有等待客户端广播通知,引发竞争。

这种设计差异使得公平锁能保证先到先得的公平性,而非公平锁则通过竞争获得更高的吞吐量。

高级特性

1. 锁续期(Watchdog)

当不指定锁超时时间时,Redisson 会启动看门狗线程自动续期:

// 无超时时间参数,启动自动续期
fairLock.lock();

// 后台线程每10秒续期一次(默认1/3看门狗超时时间)

2. 多锁管理(MultiLock)

RLock lock1 = redissonClient.getFairLock("lock1");
RLock lock2 = redissonClient.getFairLock("lock2");

RedissonMultiLock multiLock = new RedissonMultiLock(lock1, lock2);
multiLock.lock();
try {
    // 同时获得多个锁
} finally {
    multiLock.unlock();
}

性能优化建议

  1. 减少锁粒度:根据业务拆分多个细粒度锁
  2. 设置合理超时:避免锁持有时间过长
  3. 监控锁等待时间:
    long waitTime = System.currentTimeMillis();
    if (fairLock.tryLock()) {
        long acquiredTime = System.currentTimeMillis() - waitTime;
        // 记录等待时间指标
    }
    
  4. 避免嵌套锁:防止死锁发生

典型应用场景

  1. 订单处理系统:按照订单创建顺序处理
  2. 资源分配系统:公平分配有限资源
  3. 定时任务调度:确保任务按提交顺序执行
  4. 分布式工作队列:保证任务处理顺序性

通过合理使用 Redisson 公平锁,可以在分布式系统中实现公平的资源分配,避免某些客户端长时间等待导致的"饥饿"问题,特别适合需要严格顺序执行的业务场景。

8. A B 两个服务的客户端唯一标识应该不一样,那么 A加的锁,B识别不到吧,那么自己加自己的锁,就不是分布式的呀

我们讨论的是Redisson分布式锁的实现机制。您提到的结构确实如此:Redisson使用Redis的Hash结构存储锁信息,其中:

  • 键(key)是锁的名称,例如"myLock"。

  • 字段(field)是客户端唯一标识,由UUID(每个Redisson客户端实例有一个唯一的UUID)和线程ID组成。

  • 值(value)是锁的重入次数(计数器)。

现在,问题来了:服务A和服务B是两个不同的服务,它们各自启动一个Redisson客户端实例,那么它们的UUID肯定是不同的。因此,服务A加的锁,服务B在尝试获取同一把锁(同一个key)时,看到的Hash中的field(即客户端标识)是服务A的,而不是自己的。那么,服务B如何知道自己不能获取锁呢?这会不会导致服务B自己加自己的锁,从而破坏了分布式锁的互斥性?

答案是:不会。因为Redisson的分布式锁机制保证了互斥性。下面我来详细解释:

  1. 加锁机制:

当服务A要获取锁"myLock"时,它会执行一段Lua脚本(保证原子性):

  • 首先检查锁是否存在(即是否存在key为"myLock"的Hash)。

  • 如果不存在,则创建这个Hash,并设置一个字段(field为服务A的UUID+线程ID),值为1(重入次数)。同时设置一个过期时间(避免死锁)。

  • 如果存在,再检查这个Hash中是否已经包含服务A的UUID+线程ID的字段:

  • 如果存在,则重入:将值加1,并重新设置过期时间。

  • 如果不存在,说明是其他客户端(比如服务B)持有锁,那么加锁失败。

所以,服务B在尝试获取锁时,会执行同样的Lua脚本,发现锁已经存在(服务A创建的),并且字段不是自己的,那么它就会加锁失败。

  1. 锁互斥:

服务B在加锁失败后,并不会自己创建一个新的锁(即不会覆盖服务A的锁),而是会进入等待状态(通过Redis的发布订阅机制监听锁释放事件),或者根据tryLock的参数进行重试或直接返回失败。

  1. 解锁机制:

当服务A释放锁时,它会执行另一个Lua脚本:

  • 检查锁的Hash中对应自己客户端标识(UUID+线程ID)的值(重入次数):

  • 如果值大于1,则减1(因为可重入,可能多次加锁)。

  • 如果值等于1,则删除这个字段,并且删除整个key(因为Hash空了)。

同时,服务A会发布一个消息到对应的频道,通知其他等待的客户端(如服务B)锁已经被释放。

因此,整个过程中,虽然服务A和服务B有不同的客户端标识,但Redisson通过上述机制保证了同一时间只有一个客户端(即一个服务的一个线程)能持有锁。

所以,您担心的“自己加自己的锁”的情况不会发生。服务B在尝试获取锁时,会检查当前锁的持有者是否是它自己(通过自己的UUID+线程ID去匹配),如果不是,它就不会获取锁,也不会覆盖已有的锁。

总结:Redisson的分布式锁正是通过这种客户端唯一标识来区分不同的客户端,从而保证只有持有锁的客户端才能释放锁,并且不同客户端之间互斥地获取锁。

补充一点:同一个服务内的不同线程,它们的客户端UUID相同(因为同一个Redisson实例),但线程ID不同,所以同一个服务内的不同线程也会互斥(除非是同一个线程的重入)

9.

10.

11.

12.

13.

14.

15.

springboot整合redisson(一)搭建Redisson环境 一、创建springboot项目 1.通过idea创建springboot项目 2.通过web网站创建springboot项目 创建完之后的项目结构如下: 二、引入redisson依赖 由于我们是springboot整合redisson,所以我们只需引入springboot-redisson-starter就可以了,不过这里需要注意springboot与redisson的版本,因为官方推荐redisson版本与springboot版本配合使用。 将 Redisson 与 Spring Boot 库集成 阅读详情

相关推荐

Redisson 框架详解

Redisson 是一个基于 Redis 的高效 Java 客户端,封装了 Redis 的大部分功能,提供了更为丰富和高效的操作接口,能够帮助开发者更便捷地进行分布式缓存、分布式锁、分布式集合等操作。它不仅支持 Redis 的基本操作,还提供了更多的高级功能,如分布式锁、分布式集合、分布式计数器等,可以大大简化分布式应用的开发。

记得开心一点嘛的博客 2570

RedissonClient 如何初始化

RedissonClient 初始化项目方案 项目概述 Redis 是一个广泛使用的高性能键值数据库,通过其丰富的数据结构,可以有效地管理应用程序的数据。Redisson 是一个开源的 Java 客户端,利用 Redis 提供了更高级的功能,如分布式锁、配置管理、分布式集合等。在本项目中,我们将探讨如何初始化 Rediss...

weixin_41182235的博客 774

RedisTemplate和Redisson的区别

一、功能方面:Redisson: java代码解读复制代码上述代码首先创建了 Redisson 的配置对象,将 Redis 服务地址添加进去,接着创建 Redisson 客户端。通过 方法获取一个锁对象,使用 方法加锁,执行完操作后用 方法解锁。这样就实现了分布式锁的操作,而且 Redisson 的锁支持可重入、公平锁等高级特性,能很好地处理分布式环境下的并发问题。支持异步操作,可利用 接口来实现异步调用,提高系统的并发性能。例如,获取锁时可以使用 方法,后续可对 进行相应处理,充分利用异

sc35262的博客 1510

Redis(六):Redis客户端初始化

1. 客户端状态:struct redisClient 1.1 标志flags 1.2 输入缓冲区querybuf 1.3 命令argv和命令参数个数argc 1.4 命令实现函数cmd 1.5输出缓冲区buf和reply 1.6身份验证authenticated 2. 客户端的创建 2.1 相关数据结构 2.2 主函数 2.3 连接服务器的函数 Redis是一个典型的一对多的服务程序,一个服务器可以和多个客户端建立网...

蓬莱道人的博客 1241

Redisson详解

本文来说下一个强大的redis框架Redisson 文章目录概述 概述 Redisson 是 Java 的 Redis 客户端之一,提供了一些 API 方便操作 Redis。但是 Redisson 这个客户端可有点厉害,该项目已经托管到github,官网如下图所示。 官网:https://github.com/redisson ...

wh柒八九的博客 5464

人工智能训练师认证教程(5)使用MONAI进行医学影像分析的完整指南

本文介绍了使用MONAI框架进行医学影像分析的全流程。首先详细说明了环境搭建步骤,包括PyTorch和MONAI的安装配置。然后以肺部CT 3D分割为例,分步骤讲解了数据准备与预处理、3D UNet模型构建、训练配置(DiceLoss损失函数、Adam优化器等)以及训练验证循环的实现。文章还包含推理可视化方法和模型导出为ONNX格式的部署方案,并强调了医学影像分析中的数据格式适配、强度归一化、显存优化等关键注意事项。最后指出MONAI的医学专用组件可大幅简化开发流程,建议后续可探索SwinUNETR等进阶方

华为开发者布道师,天府英才计划,致力于大数据+AI 的应用创新,助力企业与个人AI创新赋能。 1207

Redisson之RAtomicLong

package bright.redisson; import org.redisson.Redisson; import org.redisson.api.RAtomicLong; import org.redisson.api.RedissonClient; import org.redisson.config.Config; import org.redisson.config.Sing...

look4liming的专栏 1万+

立创星火计划:基于STM32H743VIH6的Maverick_H743_MK1.0高性能开源飞控硬件全解析

本文详细解析了基于STM32H743VIH6核心的Maverick_H743_MK1.0高性能开源飞控硬件设计。重点阐述了采用双IMU冗余设计、高精度气压计、多路独立电源管理以及丰富接口(如CAN总线)的考量,旨在为穿越机、科研无人机等平台提供强大、可靠的飞行控制解决方案。

weixin_28787801的博客 195

RedissonClient使用方法

RedissonClient是Redisson提供的Java客户端,用于与Redis数据库进行交互。通过RedissonClient可以进行各种Redis操作,比如字符串操作、哈希操作、列表操作等。在你的项目中引入Redisson的依赖,可以通过Maven或Gradle进行管理。2. 创建RedissonClient实例。3. 使用RedissonClient。4. 关闭RedissonClient。// 在列表尾部添加元素。// 获取列表第一个元素。// 获取列表所有元素。

weixin_60246228的博客 3942

Cadence Virtuoso里搞定斩波运放AC仿真:PSS+PAC保姆级设置避坑指南

然而,当工程师们尝试在Cadence Virtuoso环境中对这种特殊结构进行AC特性分析时,往往会遇到传统AC仿真方法失效的困境——这正是PSS(Periodic Steady-State)与PAC(Periodic AC)仿真组合大显身手的场景。实际项目中我们常采用"先快后精"的两步法:先用快速设置确认大体趋势,再针对关键频段进行精细仿真。例如某次设计迭代中,将harmonics从10增加到20后,发现在1MHz处的相位裕度估算误差达15°,这解释了之前样机测试时的振荡问题。

weixin_33508411的博客 449

手把手教你搞定JBI投稿:从Statement of Significance到Declaration Statement的保姆级避坑指南

本文提供了一份详细的JBI投稿指南,重点解析Statement of Significance和Declaration of Interests的撰写技巧,帮助研究者避开常见格式陷阱。通过实战案例和检查清单,确保投稿符合JBI的学术严谨性和临床转化价值要求,提升稿件通过率。

weixin_29278805的博客 617

Redisson

Redisson

蔡林浩的博客 1025

4.UE数字人工程运行逻辑及程序逻辑

UE数字人工程运行逻辑及程序逻辑

6084

【redisson】redisson分布式锁原理分析

为什么要有分布式锁 分布式锁是基于什么延伸出来的?这个可以在博主首页搜索:超卖, 里面通过超卖例子说明分布式锁和传统锁的区别,本文重点阐述的是redisson的api使用及其源码分析。

孟秋与你的博客 1404

SKUA-GOCAD入门教程-第八节 线的创建与编辑7和8

本文介绍了曲线编辑操作的主要功能,包括曲线部分和区域的管理操作。在曲线部分操作方面,详细说明了如何合并、删除、移动和过滤曲线部分,支持精确或带公差的合并方式。在曲线区域操作方面,阐述了保留/删除区域点、移动区域点、保留/删除区域线段等操作。此外还介绍了节点连接功能,包括新增/删除连接、端点连接以及为曲线赋予地质特征的方法。

江洋大葱的博客 390

RK3576 Buildroot 双机 ADB 异常排障实录:同版 `boot.img`,一台可识别一台不可识别

进程在跑”不等于“USB 枚举成功”,adbd存活只是必要不充分条件。生产环境中的全局别名可能反向污染系统脚本。shell 命令替换中的字符串问题,必须做字节级验证(od -tx1相比“改环境规避”,核心脚本对输入做鲁棒处理更可长期维护。

小灰灰的博客 209

Redisson之RMap

package bright.redisson; import java.util.concurrent.TimeUnit; import org.redisson.Redisson; import org.redisson.api.RLock; import org.redisson.api.RMap; import org.redisson.api.RedissonClient; imp...

look4liming的专栏 9851

LPDDR6 技术标准详解(JESD209-6)

是继 LPDDR5/5X 之后的新一代低功耗 DRAM 标准,专为满足移动终端、AI、边缘计算等高带宽、低功耗场景而设计。该标准通过全新架构、动态功耗控制机制和增强型数据完整性机制,实现性能、能效与可靠性的全面升级。LPDDR6 并非仅是速度升级,更是内存架构设计思路的演进,围绕“低功耗 + 高带宽 + 强安全”的三维目标,构建下一代 SoC 平台关键基础。✅ 高带宽:支持 32B/64B 动态突发✅ 低功耗:动态电压、通道切换✅ 高可靠性:ECC + 自测试 + 安全区。

weixin_43199439的博客 2567

Redisson使用场景及原理

Redis是一个开源的高性能键值存储数据库,它提供了多种数据结构来存储数据,如字符串、哈希、列表、集合、有序集合等。Redis将数据存储在内存中,以提供快速的读写访问速度,并且能够通过异步的方式将数据持久化到磁盘上。它支持复制、Lua脚本、事务处理、不同级别的持久化选项以及多种客户端语言的接口。Redis广泛用于缓存、消息队列、短时数据存储和高性能的应用场景中。

不懂的博客 1919

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Spring Boot 整合 Redisson 实现分布式锁详解

摘要:本文介绍了在Spring Boot项目中整合Redisson实现分布式锁的完整方案。首先阐述了分布式锁的基础概念和核心特性(互斥性、安全性、可用性等),对比了主流实现方案。重点讲解了Redisson的优势(可重入锁、自动续约等)及其典型应用场景(库存扣减、任务调度等)。最后详细给出了Spring Boot整合Redisson的具体步骤,包括环境配置、依赖添加、RedissonClient注入和分布式锁的代码实现示例.

深耕 Java 后端与企业级软件架构设计,专注微服务、分布式系统、大模型 AI 应用架构落地。 2138

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Redisson之RBucket

package bright.redisson; import org.redisson.Redisson; import org.redisson.api.RBucket; import org.redisson.api.RedissonClient; import org.redisson.config.Config; import org.redisson.config.SingleSe...

look4liming的专栏 1万+

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Redisson之RBoundedBlockingQueue

package bright.redisson; import org.redisson.Redisson; import org.redisson.api.RAtomicLong; import org.redisson.api.RBoundedBlockingQueue; import org.redisson.api.RedissonClient; import org.redisson...

look4liming的专栏 4363
上一篇: 依赖-yl-常用的jar包--yn
下一篇: springmvc-调用链路
吧啦蹦吧
博客等级 码龄10年 52粉丝 139原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值