[Open Source] A simple, easy-to-use, high-performance distributed lock supporting multiple implementations, with powerful features and strong extensibility
![[Open Source] A simple, easy-to-use, high-performance distributed lock supporting multiple implementations, with powerful features and strong extensibility](https://yy123.ink/api/img/1782590159042-u0gbmr.jpg)
1. Project Overview

A simple, high-performance distributed lock that supports multiple strategies
lock4j is a distributed lock component that provides various implementations to meet different performance and environment requirements.
Our goal is to build a simple yet feature-rich distributed lock component.
2. Open Source License
Licensed under Apache-2.0
3. Screenshots

4. Feature Overview
Declarative and programmatic distributed locks based on Spring AOP, supporting RedisTemplate, Redisson, and Zookeeper.
Features
- Easy to use, powerful, and highly extensible.
- Supports Redisson, redisTemplate, and zookeeper. They can be used together, and the component supports extensibility.
5. Tech Stack
How to Use
1. Add the relevant dependencies (multiple implementations can coexist, allowing different locking implementations for different methods).
<dependencies>
<!--If you use redisTemplate as the underlying implementation for distributed locks, add the following dependency-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>lock4j-redis-template-spring-boot-starter</artifactId>
<version>${latest.version}</version>
</dependency>
<!--If you use redisson as the underlying implementation for distributed locks, add the following dependency-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>lock4j-redisson-spring-boot-starter</artifactId>
<version>${latest.version}</version>
</dependency>
<!--If you use zookeeper as the underlying implementation for distributed locks, add the following dependency-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>lock4j-zookeeper-spring-boot-starter</artifactId>
<version>${latest.version}</version>
</dependency>
</dependencies>
2. Configure Redis or Zookeeper according to your underlying implementation.
spring:
redis:
host: 127.0.0.1
...
coordinate:
zookeeper:
zkServers: 127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183
3. Use the Lock4j annotation wherever distributed locking is required.
@Service
public class DemoService {
//Default lock acquisition timeout is 3 seconds, and lock expiration time is 30 seconds
@Lock4j
public void simple() {
//do something
}
//Fully configurable, supports SpEL
@Lock4j(keys = {"#user.id", "#user.name"}, expire = 60000, acquireTimeout = 1000)
public User customMethod(User user) {
return user;
}
}
Advanced Usage
1. Configure the global default lock acquisition timeout and lock expiration time.
lock4j: acquire-timeout: 3000 #Default value is 3s; optional expire: 30000 #Default value is 30s; optional primary-executor: com.baomidou.lock.executor.RedisTemplateLockExecutor #Default priority: redisson>redisTemplate>zookeeper; optional lock-key-prefix: lock4j #Lock key prefix; default value is lock4j; optional
acquire-timeout can be understood as the maximum time spent waiting in the queue. If this time is exceeded, the process stops waiting and throws a lock acquisition timeout exception.
Why is this parameter necessary? In reality, would you keep waiting in a queue indefinitely? Wouldn't it cause problems if everyone kept waiting indefinitely?
expire is the lock expiration time. It is mainly used to prevent deadlocks. It is recommended that you estimate how long your lock-protected method takes to execute. Normally, simple CRUD operations without complex business logic take only a few seconds. Allow some extra time for safety; 10 seconds is sufficient. Our default of 30 seconds is intended to accommodate most scenarios.
2. Custom Executors.
@Service
public class DemoService {
//You can specify an executor at the method level. If you implement your own executor, you must register it with Spring in advance.
@Lock4j(executor = RedissonLockExecutor.class)
public Boolean test() {
return "true";
}
}
3. Custom Lock Key Generators.
The default lock key generator is com.baomidou.lock.DefaultLockKeyBuilder 。
@Component
public class MyLockKeyBuilder extends DefaultLockKeyBuilder {
@Override
public String buildKey(MethodInvocation invocation, String[] definitionKeys) {
String key = super.buildKey(invocation, definitionKeys);
// do something
return key;
}
}
4. Custom Lock Acquisition Failure Strategies.
The default lock acquisition failure strategy is com.baomidou.lock.DefaultLockFailureStrategy 。
@Component
public class MyLockFailureStrategy implements LockFailureStrategy {
@Override
public void onLockFailure(String key, long acquireTimeout, int acquireCount) {
// write my code
}
}
5. Manual Locking and Unlocking.
@Service
public class ProgrammaticService {
@Autowired
private LockTemplate lockTemplate;
public void programmaticLock(String userId) {
// Various query operations do not require locking
// ...
// Acquire the lock
final LockInfo lockInfo = lockTemplate.lock(userId, 30000L, 5000L, RedissonLockExecutor.class);
if (null == lockInfo) {
throw new RuntimeException("The operation is being processed. Please try again later.");
}
// Lock acquired successfully, process the business logic
try {
System.out.println("Executing simple method 1, current thread:" + Thread.currentThread().getName() + ", counter:" + (counter++));
} finally {
// Release the lock
lockTemplate.releaseLock(lockInfo);
}
// End
}
}
6. Do not release the lock within a specified period (rate limiting)
@Service
public class DemoService {
// Each user can access this method only once every 5 seconds
@Lock4j(keys = {"#user.id"}, acquireTimeout = 0, expire = 5000, autoRelease = false)
public Boolean test(User user) {
return "true";
}
}