基于Redis的分布式锁
Redis介绍
Redis是一个开源的高性能Key-Value数据库,和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型),主要用来实现缓存,也可以用来实现分布式锁。
Redis的简单操作:
- 1、set key value 用于增加数据到数据库中
- 2、setnx key value 用于添加键值对,如果该key值不存在,则成功添加并返回1,如果该key值存在则不操作并返回0
- 3、del key value 用于删除指定的key-value对
- 4、expire key seconds 用于为指定Key值设定过期时间,单位是秒
- 5、pexpire key milliseconds 用于为指定的Key值设定过期时间,单位是毫秒
- 6、keys * 用于查看当前数据库中存在的Key-value对
基于Redis实现分布式锁的原理
Redis是一种基于内存的高性能key-value数据库,具有以下优点:
a.单线程,利用redis队列技术并将访问变为串行访问,消除了传统数据库串行控制的开销
b.redis具有快速和持久化的特征,速度快,因为数据存在内存中。
c.分布式 读写分离模式
d.支持丰富数据类型
e.支持事务,操作都是原子性,所谓原子性就是对数据的更改要么全部执行,要不全部不执行。
f.可用于缓存,消息,按key设置过期时间,过期后自动删除
其单线程和原子性操作保是其可以作为分布式锁是实现方案的基础。
实现Redis分布式锁主要基于三条操作
setnx key value
expire key seconds
del key value
实现过程
0、说明
我们设计一个车票秒杀平台,假设车票剩余100个,每个顾客都是一个线程,都仅尝试购买一张票,模拟120个并发的线程,将有100个线程获得资源并抢到车票,剩余线程将显示无法没有剩余车票。
1、设计一个Ticketout类
用于维护库存信息,并出售车票,具体代码如下:
package redis;
public class Ticketout {
private static int ticketnum = 100;//所有卖票系统对应一个存票系统
public int sellTicket() {
if (ticketnum > 0) {
return ticketnum--;
}
return -1;
}
public int getTicketnum() {
return ticketnum;
}
}
当余票大于0时,才会卖出车票,并且库存减1。
2、设计一个车票售卖类
用来模拟顾客买票的线程,具体程序如下:
package redis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import java.util.concurrent.locks.Lock;
public class SellT