redis分布式锁可以通过两种框架进行实现,jedis和redisson
Jedis,功能更为全面,和redis的Java方法(api)保持一致。
使用阻塞的I/O,且其方法调用都是同步的,程序流需要等到sockets处理完I/O才能执行,不支持异步。Jedis客户端实例不是线程安全的,所以需要通过连接池来使用Jedis。
Redisson,功能较为简单,不支持排序、事物、管道、分区等redis的特性。
使用非阻塞的I/O和基于Netty框架的事件驱动的通信层,其方法调用是异步的。Redisson的API是线程安全的,所以可以操作单个Redisson连接来完成各种操作。
在进行redis编程之前,要先安装redis服务器,安装软件的下载地址
https://github.com/microsoftarchive/redis/releases
msi的镜像按照顺序,全部进行勾选进行安装即可,压缩包则通过cmd命令进行启动,个人更偏向于windows服务启动的方式,因为不用非要开着一个窗口
下面就创建一个简单的redisson锁的小程序(此处是基于springboot进行的开发)
1、在pom.xml中添加依赖
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.2.3</version>
</dependency>
2、编写redisson封装方法
package com.cl.test.rediss.services;
import org.redisson.Redisson;
import org.redisson.api.RAtomicLong;
import org.redisson.api.RBucket;
import org.redisson.api.RCountDownLatch;
import org.redisson.api.RDeque;
import org.redisson.api.RList;
import org.redisson.api.RLock;
import org.redisson.api.RMap;
import org.redisson.api.RQueue;
import org.redisson.api.RSet;
import org.redisson.api.RSortedSet;
import org.redisson.api.RTopic;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class RedisUtils {
private static Logger logger = LoggerFactory.getLogger(RedisUtils.class);
private static RedisUtils redisUtils;
/**
* 提供单例模式
* @return
*/
public static RedisUtils getInstance(){
if(redisUtils==null)
synchronized (RedisUtils.class) {
if(redisUtils==null) redisUtils=new RedisUtils();
}
return redisUtils;
}
/**
* 使用config创建Redisson
* Redisson是用于连接Redis Server的基础类
* @param config
* @return
*/
public RedissonClient getRedisson(Config config){
RedissonClient redisson=Redisson.create(config);
logger.info("成功连接Redis Server");
return redisson;
}
/**
* 使用ip地址和端口创建Redisson
* @param ip
* @param port
* @return
*/
public RedissonClient getRedisson(String ip,String port){
Config config=new Config();
config.useSingleServer().setAddress(ip+":"+port);
RedissonClient redisson=Redisson.create(config);
logger.info("成功连接Redis Server"+"\t"+"连接"+ip+":"+port+"服务器");
return redisson;
}
/**
* 关闭Redisson客户端连接
* @param redisson
*/
public void closeRedisson(RedissonClient redisson){
redisson.shutdown();
logger.info("成功关闭Redis Client连接");
}
/**
* 获取字符串对象
* @param redisson
* @param objectName
* @return
*/
public <T> RBucket<T> getRBucket(RedissonClient redisson,String objectName){
RBucket<T> bucket=redisson.getBucket(objectName);
return bucket;
}
/**
* 获取Map对象
* @param redisson
* @param objectName
* @return
*/
public <K,V> RMap<K, V> getRMap(RedissonClient redisson,String objectName){
RMap<K, V> map=redisson.getMap(objectName);
return map;
}
/**
* 获取有序集合
* @param redisson
* @param objectName
* @return
*/
public <V> RSortedSet<V> getRSortedSet(RedissonClient redisson,String objectName){
RSortedSet<V> sortedSet=redisson.getSortedSet(objectName);
return sortedSet;
}
/**
* 获取集合
* @param redisson
* @param objectName
* @return
*/
public <V> RSet<V> getRSet(RedissonClient redisson,String objectName){
RSet<V> rSet=redisson.getSet(objectName);
return rSet;
}
/**
* 获取列表
* @param redisson
* @param objectName
* @return
*/
public <V> RList<V> getRList(RedissonClient redisson,String objectName){
RList<V> rList=redisson.getList(objectName);
return rList;
}
/**
* 获取队列
* @param redisson
* @param objectName
* @return
*/
public <V> RQueue<V> getRQueue(RedissonClient redisson,String objectName){
RQueue<V> rQueue=redisson.getQueue(objectName);
return rQueue;
}
/**
* 获取双端队列
* @param redisson
* @param objectName
* @return
*/
public <V> RDeque<V> getRDeque(RedissonClient redisson,String objectName){
RDeque<V> rDeque=redisson.getDeque(objectName);
return rDeque;
}
/**
* 此方法不可用在Redisson 1.2 中
* 在1.2.2版本中 可用
* @param redisson
* @param objectName
* @return
*/
/**
public <V> RBlockingQueue<V> getRBlockingQueue(RedissonClient redisson,String objectName){
RBlockingQueue rb=redisson.getBlockingQueue(objectName);
return rb;
}*/
/**
* 获取锁
* @param redisson
* @param objectName
* @return
*/
public RLock getRLock(RedissonClient redisson,String objectName){
RLock rLock=redisson.getLock(objectName);
return rLock;
}
/**
* 获取原子数
* @param redisson
* @param objectName
* @return
*/
public RAtomicLong getRAtomicLong(RedissonClient redisson,String objectName){
RAtomicLong rAtomicLong=redisson.getAtomicLong(objectName);
return rAtomicLong;
}
/**
* 获取记数锁
* @param redisson
* @param objectName
* @return
*/
public RCountDownLatch getRCountDownLatch(RedissonClient redisson,String objectName){
RCountDownLatch rCountDownLatch=redisson.getCountDownLatch(objectName);
return rCountDownLatch;
}
/**
* 获取消息的Topic
* @param redisson
* @param objectName
* @return
*/
public <M> RTopic<M> getRTopic(RedissonClient redisson,String objectName){
RTopic<M> rTopic=redisson.getTopic(objectName);
return rTopic;
}
}
3、新建一个service,实现redisson的加锁,即需要进行加锁的方法
package com.cl.test.rediss.services;
import java.util.concurrent.TimeUnit;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.config.SingleServerConfig;
import org.springframework.stereotype.Service;
@Service
public class ZeroService {
public ZeroService(){
}
public void SysPrint() throws InterruptedException{
Config config = new Config();
SingleServerConfig singleServerConfig = config.useSingleServer();
singleServerConfig.setAddress("127.0.0.1:6379");
RedissonClient redissonClient = RedisUtils.getInstance().getRedisson(config);
for(int j = 0;j<10;j++){
RLock rlock = redissonClient.getLock("lock");
System.out.println("创建锁");
try {
boolean flag = rlock.tryLock(1,1, TimeUnit.SECONDS);//第一个参数代表等待时间,第二是代表超过时间释放锁,第三个代表设置的时间制
if(flag){
System.out.println("*************加锁成功*************");
}else{
System.out.println("*************加锁失败*************");
}
}
finally{
rlock.unlock();
System.out.println("*************解锁**********");
}
}
}
}
4、调用加了锁的方法
package com.cl.test.rediss.resources;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.cl.test.rediss.services.*;
import com.cl.test.rediss.services.ZeroService;
@RestController
public class Resource {
private ZeroService zeroService;
@Autowired
public Resource(ZeroService zeroService, Mythread mythread){
this.zeroService = zeroService;
this.mythread = mythread;
}
@RequestMapping("/zero")
public void ZeroSys() throws Exception{
zeroService.SysPrint();
}
}
5、在控制台进行调用:http://localhost:8080/zero
输出结果为:
2019-07-29 09:58:01.028 INFO 7332 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring FrameworkServlet 'dispatcherServlet'
2019-07-29 09:58:01.028 INFO 7332 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started
2019-07-29 09:58:01.093 INFO 7332 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 65 ms
2019-07-29 09:58:01.250 INFO 7332 --- [nio-8080-exec-1] org.redisson.Version : Redisson 3.2.3
2019-07-29 09:58:01.463 INFO 7332 --- [isson-netty-1-6] o.r.c.pool.SinglePubSubConnectionPool : 1 connections initialized for /127.0.0.1:6379
2019-07-29 09:58:01.463 INFO 7332 --- [isson-netty-1-5] o.r.c.pool.MasterConnectionPool : 10 connections initialized for /127.0.0.1:6379
2019-07-29 09:58:01.466 INFO 7332 --- [nio-8080-exec-1] com.cl.test.rediss.services.RedisUtils : 成功连接Redis Server
创建锁
*************加锁成功*************
*************解锁**********
创建锁
*************加锁成功*************
*************解锁**********
创建锁
*************加锁成功*************
*************解锁**********
创建锁
*************加锁成功*************
*************解锁**********
创建锁
*************加锁成功*************
*************解锁**********
创建锁
*************加锁成功*************
*************解锁**********
创建锁
*************加锁成功*************
*************解锁**********
创建锁
*************加锁成功*************
*************解锁**********
创建锁
*************加锁成功*************
*************解锁**********
创建锁
*************加锁成功*************
*************解锁**********