Principle:
Gets the specified name key if present, if there is no key, if there is no value assigned to the key, then set the expiration time;
The logic to unlock deletes the key.
1. Custom class
Package com.xxx.cloud.assets.redis.lock;
Import java.util.Collections;
Import Java.util.UUID;
Import Java.util.concurrent.TimeUnit;
Import Org.springframework.data.redis.core.RedisTemplate;
Import Org.springframework.data.redis.core.script.DefaultRedisScript;
/** * Each time you use, to new lock use/public class Redislock {//Lock name private String lockname;
Lock timeout private long time;
private static final String Key_prefix = "Businessname:lock:";
Private long Randomvalue;
Private Defaultredisscript Redisscript;
Private Redistemplate redistemplate;
Private Boolean locked; Private Redislock (String lockname, long time, Redistemplate redistemplate, Defaultredisscript redisscript) {this.
Lockname = Key_prefix + lockname;
This.time = time;
This.redistemplate = redistemplate;
This.redisscript = Redisscript;
This.randomvalue = Uuid.randomuuid (). Getleastsignificantbits (); } public static Redislock NewredisLock (String lockname, Long, redistemplate redistemplate, Defaultredisscript redisscript) {return
New Redislock (Lockname, Time, Redistemplate, redisscript); public Boolean Trylock () {Boolean success = Redistemplate.opsforvalue (). Setifabsent (Lockname, Randomvalue)
;
Setifabsent corresponding to Redis setnx method locked = success;
if (success) {Redistemplate.expire (Lockname, Time, timeunit.seconds);
return success; public void UnLock () {if (locked) {Redistemplate.execute (Redisscript, collections.singletonlist
(Lockname), randomvalue);
}
}
}
2. Test code
Package com.xxx.cloud.assets.service;
Import Com.xxx.cloud.assets.redis.lock.RedisLock;
Import Com.xxx.cloud.assets.test.TestBase;
Import Org.junit.Test;
Import Org.springframework.data.redis.core.RedisTemplate;
Import Org.springframework.data.redis.core.script.DefaultRedisScript;
Import Javax.annotation.Resource;
Import Java.util.concurrent.ExecutorService;
Import java.util.concurrent.Executors;
Import Java.util.concurrent.TimeUnit; public class Testredislock extends Testbase {@Resource (name = "Redistemplate") Private redistemplate Redistempla
Te
@Resource (name = "Dellockscript") private defaultredisscript dellockscript; @Test public void Testredislock () throws Interruptedexception {Redislock lock = Redislock.newredislock ("Test"
, 1000,redistemplate,dellockscript);
try {Boolean success = Lock.trylock ();
SYSTEM.OUT.PRINTLN (Success);
}finally {lock.unlock (); }} @Test Publicvoid Testmulredislock () throws interruptedexception {final Redislock lock1 = Redislock.newredislock ("Test", 1000,r
Edistemplate,dellockscript);
Final Redislock Lock2 = Redislock.newredislock ("Test", 1000,redistemplate,dellockscript); Runnable Task1 = new Runnable () {@Override public void run () {try {bool
EAN success = Lock1.trylock ();
System.out.println ("Task1" + success);
TimeUnit.SECONDS.sleep (10);
}catch (Exception e) {e.printstacktrace ();
finally {Lock1.unlock ();
}
}
}; Runnable task2 = new Runnable () {@Override public void run () {try {bool
EAN success = Lock2.trylock ();
System.out.println ("Task2" +success);
TimeUnit.SECONDS.sleep (10); }catch (Exception e) {e.printstacktrace ();
finally {Lock2.unlock ();
}
}
};
Executorservice Executorservice = Executors.newcachedthreadpool ();
Executorservice.submit (TASK1);
Executorservice.submit (TASK2);
TimeUnit.SECONDS.sleep (15);
}
}
3.spring part of the configuration
<bean id= "Redistemplate" class= "org.springframework.data.redis.core.RedisTemplate" >
<property name= " ConnectionFactory "ref=" jedisconnectionfactory "/>
<property name=" Defaultserializer ">
<bean class= "Org.springframework.data.redis.serializer.StringRedisSerializer"/>
</property>
</ bean>
<bean id= "Dellockscript" class= "Org.springframework.data.redis.core.script.DefaultRedisScript" >
<property name= "Location" value= "Classpath:database/dellock.lua"/> <property name=
" Resulttype "value=" Java.lang.Boolean "/>
</bean>
4.dellock.lua script (can also be replaced with code logic)
If Redis.call ("Get", keys[1]) = = Argv[1] then return
redis.call ("Del", Keys[1])
else return
0