Distributed locks can be implemented in many ways, such as zookeeper, redis.... Either way, the basic principle remains the same: a state value is used to represent the lock, and the occupation and release of the lock are identified by the state value.
1. Why Redis can easily implement distributed locks
1. Redis is a single-process single-thread mode, using queues The mode turns concurrent access into serial access, and there is no competition between multiple clients' connections to Redis.
2. Redis’s SETNX command can easily implement distributed locks.
setNX(SET if Not eXists)
Syntax: SETNX key value
Return value: If the setting is successful, 1 is returned; if the setting fails, 0 is returned.
Set the value of key to value if and only if key does not exist, and return 1; if the given key already exists, SETNX does not take any action and returns 0.
To sum up, you can use the return value of setnx to determine whether the lock is acquired, and you don’t have to worry about concurrent access, because Redis is single-threaded, so if it returns 1, the lock is acquired, and 0 is returned. It was not obtained. When the business operation is completed, the lock must be released. The logic of releasing the lock is very simple, which is to delete the previously set key, so that the lock can be obtained by setnx the key next time.
2. Distributed lock implementation
We already know that distributed locks can be implemented through Redis’s own function setNX. The specific implementation steps are as follows.
I installed the Redis service in a CentOS7 Linux virtual machine. The IP address is: 192.168.246.130 and the service port is: 6379.
The following is an example of java implementing distributed locks through redis:
import redis.clients.jedis.Jedis; public class RedisLock { //锁的key private static final String key = "DistributedRedisLock"; private static Integer count = 0; public static void main(String[] args) { for(int i=0;i<1000;i++){ new Thread(new Runnable() { @Override public void run() { //获取Redis连接 Jedis jedis = new Jedis("192.168.246.130", 6379); try{ while(true){ //获取锁 if(jedis.setnx(key, Thread.currentThread().getName()) == 1){ try{ System.out.println("线程("+Thread.currentThread().getName()+")获取到锁,开始执行操作"); count++; System.out.println(count); break; }finally{ System.out.println("操作执行完成,释放锁"); //操作执行完一定要释放锁,所以在finally块中执行 jedis.del(key); } }else{ //返回的不是1,说明已经有某个线程获取到了锁 try { //等待100毫秒之后重试 Thread.sleep(100l); } catch (InterruptedException e) { e.printStackTrace(); } } } }catch(Exception e){ e.printStackTrace(); }finally{ //释放Redis连接 jedis.disconnect(); } } }).start(); } } }
The output of the above code is:
线程(Thread-320)获取到锁,开始执行操作 1 操作执行完成,释放锁 线程(Thread-463)获取到锁,开始执行操作 2 操作执行完成,释放锁 线程(Thread-997)获取到锁,开始执行操作 3 操作执行完成,释放锁 ... 线程(Thread-409)获取到锁,开始执行操作 998 操作执行完成,释放锁 线程(Thread-742)获取到锁,开始执行操作 999 操作执行完成,释放锁 线程(Thread-286)获取到锁,开始执行操作 1000 操作执行完成,释放锁
Although the above code is in a single application with multiple threads It was tested, but even if multiple applications and multiple threads are used to acquire locks in a distributed environment, the results are still correct.
3. Solve the deadlock problem
The previous example code is just a test code, just to illustrate the principle. The example itself is very simple, so there are some ill-considered aspects. . For example, after acquiring the lock, an environmental problem occurs during the execution of the business operation and the connection to Redis is disconnected. Then the lock cannot be released in the finally block, causing other threads waiting to acquire the lock to wait indefinitely, which is what happens. Deadlock phenomenon.
Solution:
You can set an expiration time for the lock in Redis, so that even if the lock cannot be released, the lock can be automatically released after a period of time.
In terms of code, you only need to add the following code to the try statement block after acquiring the lock:
jedis.expire(key, 10); //这里给锁设置10秒的过期时间
A better solution:
One solution is not very good, because when the business operation processing time is very long and exceeds the set expiration time, the lock is automatically released, and then when the operation of releasing the lock in the finally block is executed, the lock may have been used by other users. The lock held by a thread will cause the lock held by other threads to be released, thus causing concurrency problems. Therefore, a more appropriate way is to determine whether the lock has expired when releasing the lock. If it has expired, there is no need to release it again.
In the code, change the operation after acquiring the lock to the following code:
long start = System.currentTimeMillis(); //获取起始时间毫秒数 try{ jedis.expire(key, 10); ... }finally{ ... if(System.currentTimeMillis() < start+10*1000){ //如果之前设置的锁还未过期,则释放掉 jedis.del(key); } }
The above is the detailed content of Java implements distributed lock based on Redis. For more information, please follow other related articles on the PHP Chinese website!

JavaachievesplatformindependencethroughtheJavaVirtualMachine(JVM),allowingcodetorunondifferentoperatingsystemswithoutmodification.TheJVMcompilesJavacodeintoplatform-independentbytecode,whichittheninterpretsandexecutesonthespecificOS,abstractingawayOS

Javaispowerfulduetoitsplatformindependence,object-orientednature,richstandardlibrary,performancecapabilities,andstrongsecurityfeatures.1)PlatformindependenceallowsapplicationstorunonanydevicesupportingJava.2)Object-orientedprogrammingpromotesmodulara

The top Java functions include: 1) object-oriented programming, supporting polymorphism, improving code flexibility and maintainability; 2) exception handling mechanism, improving code robustness through try-catch-finally blocks; 3) garbage collection, simplifying memory management; 4) generics, enhancing type safety; 5) ambda expressions and functional programming to make the code more concise and expressive; 6) rich standard libraries, providing optimized data structures and algorithms.

JavaisnotentirelyplatformindependentduetoJVMvariationsandnativecodeintegration,butitlargelyupholdsitsWORApromise.1)JavacompilestobytecoderunbytheJVM,allowingcross-platformexecution.2)However,eachplatformrequiresaspecificJVM,anddifferencesinJVMimpleme

TheJavaVirtualMachine(JVM)isanabstractcomputingmachinecrucialforJavaexecutionasitrunsJavabytecode,enablingthe"writeonce,runanywhere"capability.TheJVM'skeycomponentsinclude:1)ClassLoader,whichloads,links,andinitializesclasses;2)RuntimeDataAr

Javaremainsagoodlanguageduetoitscontinuousevolutionandrobustecosystem.1)Lambdaexpressionsenhancecodereadabilityandenablefunctionalprogramming.2)Streamsallowforefficientdataprocessing,particularlywithlargedatasets.3)ThemodularsystemintroducedinJava9im

Javaisgreatduetoitsplatformindependence,robustOOPsupport,extensivelibraries,andstrongcommunity.1)PlatformindependenceviaJVMallowscodetorunonvariousplatforms.2)OOPfeatureslikeencapsulation,inheritance,andpolymorphismenablemodularandscalablecode.3)Rich

The five major features of Java are polymorphism, Lambda expressions, StreamsAPI, generics and exception handling. 1. Polymorphism allows objects of different classes to be used as objects of common base classes. 2. Lambda expressions make the code more concise, especially suitable for handling collections and streams. 3.StreamsAPI efficiently processes large data sets and supports declarative operations. 4. Generics provide type safety and reusability, and type errors are caught during compilation. 5. Exception handling helps handle errors elegantly and write reliable software.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

VSCode Windows 64-bit Download
A free and powerful IDE editor launched by Microsoft

WebStorm Mac version
Useful JavaScript development tools

mPDF
mPDF is a PHP library that can generate PDF files from UTF-8 encoded HTML. The original author, Ian Back, wrote mPDF to output PDF files "on the fly" from his website and handle different languages. It is slower than original scripts like HTML2FPDF and produces larger files when using Unicode fonts, but supports CSS styles etc. and has a lot of enhancements. Supports almost all languages, including RTL (Arabic and Hebrew) and CJK (Chinese, Japanese and Korean). Supports nested block-level elements (such as P, DIV),

SAP NetWeaver Server Adapter for Eclipse
Integrate Eclipse with SAP NetWeaver application server.

Notepad++7.3.1
Easy-to-use and free code editor
