在Spring中,可以使用不同的方式来实现分布式锁,例如基于数据库、Redis、ZooKeeper等

在Spring中,可以使用不同的方式来实现分布式锁,例如基于数据库、Redis、ZooKeeper等。下面是两种常见的实现方式:

  1. 使用Redis实现分布式锁:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

@Service
public class CounterService {
    private static final String LOCK_KEY = "counter_lock";
    private static final long LOCK_EXPIRE_TIME = 5000; // 锁的过期时间,单位为毫秒

    @Autowired
    private StringRedisTemplate redisTemplate;

    public void incrementCounter() {
        // 获取锁
        boolean locked = redisTemplate.opsForValue().setIfAbsent(LOCK_KEY, "locked");
        if (locked) {
            try {
                // 执行业务逻辑
                // ...
            } finally {
                // 释放锁
                redisTemplate.delete(LOCK_KEY);
            }
        } else {
            // 未获取到锁,处理逻辑
            // ...
        }
    }
}
  1. 使用自定义注解实现本地锁:
import org.springframework.stereotype.Service;

@Service
public class CounterService {
    @LocalLock(key = "counter_lock", expire = 5000)
    public void incrementCounter() {
        // 执行业务逻辑
        // ...
    }
}

以上是两种常见的在Spring中实现分布式锁的方式。第一种方式使用Redis作为分布式锁的存储介质,通过Redis的setnx命令来获取锁。第二种方式是使用自定义注解,在方法上添加注解即可实现本地锁的功能。
在Spring Boot中使用Redis实现分布式锁非常简单。你可以按照以下步骤进行操作:

  1. 首先,确保你的Spring Boot项目中已经引入了Redis的依赖。

  2. 在配置文件中配置Redis的连接信息,包括主机名、端口号、密码等。

  3. 创建一个RedisTemplate对象,用于操作Redis数据库。

  4. 使用RedisTemplate的opsForValue()方法获取一个ValueOperations对象,用于操作Redis中的键值对。

  5. 使用setIfAbsent()方法尝试设置一个键值对,如果该键不存在,则设置成功并返回true,表示获取到了分布式锁。

  6. 设置一个过期时间,确保在一定时间内锁会自动释放。

  7. 在锁内执行需要保护的代码。

  8. 执行完毕后,使用delete()方法删除该键,释放锁。

下面是一个示例代码,演示了如何在Spring Boot中使用Redis实现分布式锁:

@Autowired
private RedisTemplate<String, String> redisTemplate;

public boolean acquireLock(String lockKey, String requestId, int expireTime) {
    ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
    Boolean result = valueOperations.setIfAbsent(lockKey, requestId, expireTime, TimeUnit.SECONDS);
    return result != null && result;
}

public void releaseLock(String lockKey, String requestId) {
    ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
    String value = valueOperations.get(lockKey);
    if (value != null && value.equals(requestId)) {
        redisTemplate.delete(lockKey);
    }
}

请注意,以上代码仅为示例,实际使用时需要根据具体业务需求进行适当的修改和优化。
RedisTemplate的opsForValue()方法提供了一些常用的操作,包括:

  1. set(key, value):将指定的key和value存储到Redis中。
  2. get(key):根据指定的key从Redis中获取对应的value。
  3. increment(key, delta):将指定key的value增加指定的delta值。
  4. decrement(key, delta):将指定key的value减少指定的delta值。
  5. append(key, value):将指定的value追加到指定key的value末尾。
  6. getAndSet(key, value):将指定key的value设置为新值,并返回旧值。
  7. size(key):获取指定key的value的长度。
  8. setIfAbsent(key, value):当指定key不存在时,将key和value存储到Redis中。
  9. setIfPresent(key, value):当指定key存在时,将key和value存储到Redis中。
  10. multiSet(map):将多个key-value对存储到Redis中。
  11. multiGet(keys):根据指定的多个key从Redis中获取对应的values。

以下是一个示例代码,演示了如何使用RedisTemplate的opsForValue()方法进行操作:

// 获取ValueOperations对象
ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();

// 设置key和value
valueOperations.set("key1", "value1");

// 获取key对应的value
String value = valueOperations.get("key1");

// 增加key对应的value
valueOperations.increment("key1", 10);

// 减少key对应的value
valueOperations.decrement("key1", 5);

// 追加value到key对应的value末尾
valueOperations.append("key1", "value2");

// 获取key对应的value的长度
Long size = valueOperations.size("key1");

// 设置新值并返回旧值
String oldValue = valueOperations.getAndSet("key1", "new value");

// 当key不存在时,设置key和value
valueOperations.setIfAbsent("key2", "value2");

// 当key存在时,设置key和value
valueOperations.setIfPresent("key2", "new value2");

// 存储多个key-value对
Map<String, String> map = new HashMap<>();
map.put("key3", "value3");
map.put("key4", "value4");
valueOperations.multiSet(map);

// 获取多个key对应的values
List<String> values = valueOperations.multiGet(Arrays.asList("key3", "key4"));

RedisTemplate是Spring Data Redis提供的一个用于操作Redis的模板类。通过RedisTemplate,我们可以方便地对有序集合(Sorted Set)进行操作。下面是使用RedisTemplate操作有序集合的示例代码:

  1. 添加成员到有序集合中:
redisTemplate.opsForZSet().add("mySortedSet", "member1", 1.0);
redisTemplate.opsForZSet().add("mySortedSet", "member2", 2.0);
redisTemplate.opsForZSet().add("mySortedSet", "member3", 3.0);
  1. 获取有序集合中指定分数范围内的成员:
Set<String> members = redisTemplate.opsForZSet().rangeByScore("mySortedSet", 2.0, 3.0);
  1. 获取有序集合中指定成员的分数:
Double score = redisTemplate.opsForZSet().score("mySortedSet", "member1");
  1. 获取有序集合中指定成员的排名(从小到大排名):
Long rank = redisTemplate.opsForZSet().rank("mySortedSet", "member2");
  1. 获取有序集合中指定成员的排名(从大到小排名):
Long reverseRank = redisTemplate.opsForZSet().reverseRank("mySortedSet", "member2");
  1. 获取有序集合中指定分数范围内的成员数量:
Long count = redisTemplate.opsForZSet().count("mySortedSet", 1.0, 3.0);

请注意,以上代码示例中的"mySortedSet"是有序集合的键名,“member1”、"member2"等是成员的值,1.0、2.0等是成员的分数。
在这里插入图片描述

上一篇:【Godot4.2】2D导航02 - AstarGrid2D及其使用方法


下一篇:2024蓝桥杯每日一题(BFS)