今天看博客看到了一条关于实现分布式锁的标题,正好有空闲时间,便自己动手简单实现基于redis的分布式锁;
大体实现思路:
1.在redis中设置一个(key,value),并赋予其过期时间,防止死锁,将这个(key,value)当做一个锁,并将value返回,当释放锁的时候进行判断。 2.获取锁的时候同样设置一个过期时间,如果超时,则停止获取锁。 3.释放锁的时候,先对比判断标识,如果符合条件,则删除key,达到释放锁的目的。
具体代码:
package com
.chat
.api
.test
.redisLock
;
import redis
.clients
.jedis
.Jedis
;
import redis
.clients
.jedis
.JedisPool
;
import redis
.clients
.jedis
.Transaction
;
import java
.util
.List
;
import java
.util
.UUID
;
public class RedisLock {
private JedisPool jedisPool
;
public RedisLock(JedisPool jedisPool
){
this.jedisPool
= jedisPool
;
}
public String
addLock(String lock
,Long requestTimeout
,Long timeout
){
Jedis jedis
= null
;
String identify
= null
;
try {
jedis
= jedisPool
.getResource();
String val
= UUID
.randomUUID().toString();
String key
= lock
;
int expire
= (int) (timeout
/1000);
long end
= System
.currentTimeMillis() + requestTimeout
;
while (System
.currentTimeMillis() < end
){
if (jedis
.setnx(key
,val
) == 1){
jedis
.expire(key
,expire
);
identify
= val
;
return identify
;
};
if (jedis
.ttl(key
) == -1){
jedis
.expire(key
,expire
);
}
try {
Thread
.sleep(10);
}catch (Exception e
){
Thread
.currentThread().interrupt();
}
}
}catch (Exception e
){
e
.printStackTrace();
}finally {
if (jedis
!= null
){
jedis
.close();
}
}
return identify
;
}
public boolean releaseLock(String lock
,String identify
){
Jedis jedis
= null
;
String key
= lock
;
boolean flag
= false;
try {
jedis
= jedisPool
.getResource();
while (true){
jedis
.watch(key
);
if (identify
.equals(jedis
.get(key
))){
Transaction transaction
= jedis
.multi();
transaction
.del(key
);
List
<Object> exec
= transaction
.exec();
if (exec
== null
){
continue;
}
flag
= true;
jedis
.unwatch();
break;
}
}
}catch (Exception e
){
e
.printStackTrace();
}finally {
if (jedis
!= null
){
jedis
.close();
}
}
return flag
;
}
}
package com
.chat
.api
.test
.redisLock
;
import redis
.clients
.jedis
.JedisPool
;
import redis
.clients
.jedis
.JedisPoolConfig
;
public class TestService {
private static JedisPool pool
= null
;
private RedisLock redisLock
= new RedisLock(pool
);
int n
= 100;
static {
JedisPoolConfig config
= new JedisPoolConfig();
config
.setMaxTotal(200);
config
.setMaxIdle(10);
config
.setMaxWaitMillis(100*1000);
config
.setTestOnBorrow(true);
pool
= new JedisPool(config
,"127.0.0.1",6379,3000,"123456");
}
public void seckill(){
String identifier
= redisLock
.addLock("resource", 5000L
, 1000L
);
System
.out
.println(Thread
.currentThread().getName() + "获得了锁");
System
.out
.println(--n
);
redisLock
.releaseLock("resource", identifier
);
}
}
下面是测试代码:
package com
.chat
.api
.test
.redisLock
;
public class ThreadTest extends Thread {
private TestService service
;
public ThreadTest(TestService service
){
this.service
= service
;
}
@Override
public void run() {
service
.seckill();
}
}
package com
.chat
.api
.test
.redisLock
;
public class test {
public static void main(String
[] args
) {
TestService service
= new TestService();
for (int i
= 0; i
< 50; i
++) {
ThreadTest threadA
= new ThreadTest(service
);
threadA
.start();
}
}
}
执行结果:
转载请注明原文地址: https://lol.8miu.com/read-5462.html