Redisson分布式锁使用

不加锁问题

例如:我们在调用操作redis接口,获取key减去1在set进去。这样的操作,再遇到高并发时,大家get的数据都一样,都减去1,再set进去,这样数据肯定是错的。

	@Test
	void contextLoads() {
		Long num = (Long) redisUtil.get("num");
		num = num - 1;
		redisUtil.set("num",num);
	}

使用synchronized同步锁或者redis加锁都会有很多问题

使用redisson分布式锁

在这里插入图片描述

1、配置

1、引入依赖

<dependency>
	<groupId>org.redisson</groupId>
	<artifactId>redisson</artifactId>
	<version>3.16.1</version>
</dependency>

2、配置

@Configuration
public class RedissonConfig {
	@Value("${spring.redis.host}")
	private String host;

	@Value("${spring.redis.port}")
	private String port;

	@Value("${spring.redis.password}")
	private String password;

	@Bean
	public RedissonClient redissonClient() {
		Config config = new Config();
		// config.useClusterServers().addNodeAddress("redis://" + host + ":" + port); // 分片集群方式
		SingleServerConfig server = config.useSingleServer();
		config.setLockWatchdogTimeout(5 * 1000L);
		server.setAddress("redis://" + host + ":" + port);
		server.setPassword(password);
		RedissonClient redissonClient = Redisson.create(config);
		return redissonClient;
	}
}

2、正常加锁

@Autowired
Redisson redisson;


RLock lock = redisson.getLock("lockKey"); //获取锁
lock.lock(); //加锁,注射性等待。默认加的锁的时间是30s。
// 1)、锁自动续期,如果业务时间超长,运行期间自动给锁续上新的30s.
// 2)、加锁的业务只要运行完成,就不会给当前锁续期,即使不手动解锁,锁默认在30s以后删除



// 加锁以后10秒钟自动解锁
// 无需调用unlock方法手动解锁
// lock.lock(10, TimeUnit.SECONDS);


// 尝试加锁,最多等待100秒,上锁以后10秒自动解锁
// boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS);
try {
    // redis操作.
} finally {
    lock.unlock(); // 释放锁
}

3、读写锁

写锁没完成,就读取不到数据。保证能读到最新数据。

	@Test
	public void  write(){
		// 获取读写锁
		RReadWriteLock lock = redisson.getReadWriteLock("rw-lock");
		RLock rLock = lock.writeLock();
		try {
			rLock.lock();  // 给写加锁,写没完成,读就读不出来
			redisUtil.set("num",1);
		}finally {
			// 释放锁
			rLock.unlock();
		}
	}

	@Test
	public void  read(){
		// 获取读写锁
		RReadWriteLock lock = redisson.getReadWriteLock("rw-lock");
		RLock rLock = lock.readLock();
		rLock.lock();  // 加读锁,写锁没完成,就读不了
		try {
			redisUtil.get("num");
		}finally {
			// 释放锁
			rLock.unlock();
		}
	}

4、闭锁

调用次数为我们设置的次数后就锁住。

	@Test // 闭锁,设置次数和锁
	public void lockDoor() throws InterruptedException {
		RCountDownLatch door = redisson.getCountDownLatch("door");
		door.trySetCount(5); // 5次后就锁住
		door.await();
	}
	@Test // 闭锁  调一次,次数就减1,等到上面设置的5次后,就锁住
	public void door() throws InterruptedException {
		RCountDownLatch door = redisson.getCountDownLatch("door");
		door.countDown();
	}

5、信号量

信号量占用与释放:如设置停车场有3个车位,每次占用一个信号,等到占用到了3个,就会等待(或者可以返回false),这时再释放一个信号量,才能占用得到。

	@Test
	public void setparkCount()  {
		redisUtil.set("park",3); // 设置这个停车场有三个车位
	}
	@Test // 占用一个,如果3个都占用了,就锁住,一直等待
	public void park() throws InterruptedException {
		RSemaphore park = redisson.getSemaphore("park");
		park.acquire(); //占用一个信号,获取一个值(如:占用一个车位),堵塞性等待
		// 或者
	// boolean b = park.tryAcquire();// 占用一个信号,如果车位位,返回false
	}
	@Test // 释放一个
	public void go() throws InterruptedException {
		RSemaphore park = redisson.getSemaphore("park");
		park.release(); //释放一个信号(如: 释放一个车位)
	}
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值