GitHub Source:
Github.com/z521598/redis-lock
Implementation principle:
1.setnx
Redis's setnx Directive (document reference), setnx means set if not eXists, command format: setnx $key $value
If this key does not exist, it is set to value, the return value is 1, and if this key exists, it is not set and the return value is 0. Such as:
127.0. 0.1:6379[1]>1127.0. 0.1:6379[1]>0
Redis is single-threaded and thread-safe, and the setnx instruction is able to meet the demand for locks in high concurrency situations because of the above features.
2.springdata-redis
Springdata-redis is a template method that sends commands to REDIS and accepts data in a high-level abstraction, simply understood as "sending commands to Redis using Java and receiving data from clients" (document reference)
Configuration file: Github.com/z521598/redis-lock/blob/master/src/main/resources/applicationcontext.xml
V1 Description:
The simplest of the most coarse lock implementations, implementing 2 methods.
Method 1: Get the lock, public UUID acquire (String Lockkey, Long acquiretimeoutinmillis, long Lockexpiryinmillis)
Parameter description: Lockkey is the key;acquiretimeoutinmillis of the lock to obtain the wait time for the lock, and if the lock is discarded over this time, the Lockexpiryinmillis is the expiration time of the lock.
Return value: The value of the lock corresponding to "Setnx key value" in the command.
Ideas:
1. Call Springdata-redis's Setifabsent (Lockkey, Value) method (that is, setnx in the command line), value is a random uuid.
2. If true, indicates that the lock has been acquired, continue setting the time-out, and return the set UUID.
If False is returned, then the lock is not acquired, then hibernation is 100ms, and the total sleep time is recorded, if Lockexpiryinmillis is greater than or equal to the time the total sleep is recorded, the lock is not acquired, and Null is returned.
Method 2: Release the lock, public void release (String lockkey, uuid uuid)
Parameter description: Lockkey is the key;uuid of the lock as the value of the lock.
Idea: Check if the value of the lock is a UUID, if it is equal, then release, if not equal, do nothing; prevents the release of locks acquired by other threads.
The obvious disadvantages:
The first step is to get the lock, the second step, and then set the time-out. This is a 2-step operation, not an atomic operation, if after the first step, the program crashes or power down or redis happens to be a master-slave switch, and so on, the second step can not be performed properly, so that the lock will never be released.
Code:
PublicUUID Acquire (String Lockkey,LongAcquiretimeoutinmillis,LongLockexpiryinmillis)throwsinterruptedexception {uuid uuid=Uuid.randomuuid (); LongTimeout = 0L; while(Timeout <Acquiretimeoutinmillis) { if(Redistemplate.opsforvalue (). Setifabsent (Lockkey, uuid.tostring ())) {Redistemplate.expire (Lockkey, Lockexpiryinmillis, timeunit.milliseconds); returnuuid; } TimeUnit.MILLISECONDS.sleep (Default_acquire_resolution_millis); Timeout+=Default_acquire_resolution_millis; } return NULL; }
Lock implementation: Github.com/z521598/redis-lock/blob/master/src/main/java/com/redis/lock/sdata/v1/lockservice.java
Unit Test: Github.com/z521598/redis-lock/blob/master/src/test/java/com/redis/lock/sdata/v1/lockservicetest.java
V2 Description:
Roughly the same as V1, but the value of the lock is "expired", and if the lock is acquired, the expiration time is less than now, then the lock is considered to have expired.
Cons: (Rare occurrences)
When Redis is a master-slave form, after acquiring the lock, Master goes down, slave takes over, but this time the "new master" has not yet synchronized the lock key. At this point, the other thread acquires the lock, finds that there is no key, and acquires a lock that should not be acquired, which can cause an unsafe situation.
Code:
Lock implementation: GITHUB.COM/Z521598/REDIS-LOCK/TREE/MASTER/SRC/MAIN/JAVA/COM/REDIS/LOCK/SDATA/V2
Unit Test: Github.com/z521598/redis-lock/blob/master/src/test/java/com/redis/lock/sdata/v2/lockv2servicetest.java
V3
Please expect