您的位置:首页 > 数据库 > Redis

使用redisson实现分布式锁

2020-07-14 06:06 393 查看

Redis based distributed reentrant Lock object for Java and implements java.util.concurrent.locks.Lock interface.

If Redisson instance which acquired lock crashes then such lock could hang forever in acquired state. To avoid this Redisson maintains lock watchdog, it prolongs lock expiration while lock holder Redisson instance is alive. By default lock watchdog timeout is 30 seconds and can be changed through Config.lockWatchdogTimeout setting.

Also Redisson allow to specify leaseTime parameter during lock acquisition. After specified time interval locked lock will be released automatically.

RLock object behaves according to the Java Lock specification. It means only lock owner thread can unlock it otherwise IllegalMonitorStateException would be thrown. Otherwise consider to use RSemaphore object.

Code example:

RLock lock = redisson.getLock(“myLock”);

// traditional lock method
lock.lock();

// or acquire lock and automatically unlock it after 10 seconds
lock.lock(10, TimeUnit.SECONDS);

// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS);
if (res) {
try {

} finally {
lock.unlock();
}
}
Code example of Async interface usage:

RLock lock = redisson.getLock(“myLock”);

RFuture lockFuture = lock.lockAsync();

// or acquire lock and automatically unlock it after 10 seconds
RFuture lockFuture = lock.lockAsync(10, TimeUnit.SECONDS);

// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
RFuture lockFuture = lock.tryLockAsync(100, 10, TimeUnit.SECONDS);

lockFuture.whenComplete((res, exception) -> {

// ...

lock.unlockAsync();

});
Code example of Reactive interface usage:

RedissonReactiveClient redisson = Redisson.createReactive(config);
RLockReactive lock = redisson.getLock(“myLock”);

Mono lockMono = lock.lock();

// or acquire lock and automatically unlock it after 10 seconds
Mono lockMono = lock.lock(10, TimeUnit.SECONDS);

// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
Mono lockMono = lock.tryLock(100, 10, TimeUnit.SECONDS);

lockMono.doOnNext(res -> {
// …
})
.doFinally(lock.unlock())
.subscribe();
Code example of RxJava2 interface usage:

RedissonRxClient redisson = Redisson.createRx(config);
RLockRx lock = redisson.getLock(“myLock”);

Completable lockRes = lock.lock();

// or acquire lock and automatically unlock it after 10 seconds
Completable lockRes = lock.lock(10, TimeUnit.SECONDS);

// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
Single lockRes = lock.tryLock(100, 10, TimeUnit.SECONDS);

lockRes.doOnSuccess(res -> {
// …
})
.doFinally(lock.unlock())
.subscribe();
2. Fair Lock
Redis based distributed reentrant fair Lock object for Java implements java.util.concurrent.locks.Lock interface.

Fair lock guarantees that threads will acquire it in is same order they requested it. All waiting threads are queued and if some thread has died then Redisson waits its return for 5 seconds. For example, if 5 threads are died for some reason then delay will be 25 seconds.

If Redisson instance which acquired lock crashes then such lock could hang forever in acquired state. To avoid this Redisson maintains lock watchdog, it prolongs lock expiration while lock holder Redisson instance is alive. By default lock watchdog timeout is 30 seconds and can be changed through Config.lockWatchdogTimeout setting.

Also Redisson allow to specify leaseTime parameter during lock acquisition. After specified time interval locked lock will be released automatically.

RLock object behaves according to the Java Lock specification. It means only lock owner thread can unlock it otherwise IllegalMonitorStateException would be thrown. Otherwise consider to use RSemaphore object.

Code example:

RLock lock = redisson.getFairLock(“myLock”);

// traditional lock method
lock.lock();

// or acquire lock and automatically unlock it after 10 seconds
lock.lock(10, TimeUnit.SECONDS);

// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS);
if (res) {
try {

} finally {
lock.unlock();
}
}
Code example of Async interface usage:

RLock lock = redisson.getFairLock(“myLock”);

RFuture lockFuture = lock.lockAsync();

// or acquire lock and automatically unlock it after 10 seconds
RFuture lockFuture = lock.lockAsync(10, TimeUnit.SECONDS);

// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
RFuture lockFuture = lock.tryLockAsync(100, 10, TimeUnit.SECONDS);

lockFuture.whenComplete((res, exception) -> {
// …
lock.unlockAsync();
});
Code example of Reactive interface usage:

RedissonReactiveClient redisson = Redisson.createReactive(config);
RLockReactive lock = redisson.getFairLock(“myLock”);

Mono lockMono = lock.lock();

// or acquire lock and automatically unlock it after 10 seconds
Mono lockMono = lock.lock(10, TimeUnit.SECONDS);

// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
Mono lockMono = lock.tryLock(100, 10, TimeUnit.SECONDS);

lockMono.doOnNext(res -> {
// …
})
.doFinally(lock.unlock())
.subscribe();
Code example of RxJava2 interface usage:

RedissonRxClient redisson = Redisson.createRx(config);
RLockRx lock = redisson.getFairLock(“myLock”);

Completable lockRes = lock.lock();

// or acquire lock and automatically unlock it after 10 seconds
Completable lockRes = lock.lock(10, TimeUnit.SECONDS);

// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
Single lockRes = lock.tryLock(100, 10, TimeUnit.SECONDS);

lockRes.doOnSuccess(res -> {
// …
})
.doFinally(lock.unlock())
.subscribe();
3. MultiLock
Redis based distributed MultiLock object allows to group Lock objects and handle them as a single lock. Each RLock object may belong to different Redisson instances.

If Redisson instance which acquired MultiLock crashes then such MultiLock could hang forever in acquired state. To avoid this Redisson maintains lock watchdog, it prolongs lock expiration while lock holder Redisson instance is alive. By default lock watchdog timeout is 30 seconds and can be changed through Config.lockWatchdogTimeout setting.

Also Redisson allow to specify leaseTime parameter during lock acquisition. After specified time interval locked lock will be released automatically.

MultiLock object behaves according to the Java Lock specification. It means only lock owner thread can unlock it otherwise IllegalMonitorStateException would be thrown. Otherwise consider to use RSemaphore object.

Code example:

RLock lock1 = redisson1.getLock(“lock1”);
RLock lock2 = redisson2.getLock(“lock2”);
RLock lock3 = redisson3.getLock(“lock3”);

RLock multiLock = anyRedisson.getMultiLock(lock1, lock2, lock3);

// traditional lock method
multiLock.lock();

// or acquire lock and automatically unlock it after 10 seconds
multiLock.lock(10, TimeUnit.SECONDS);

// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
boolean res = multiLock.tryLock(100, 10, TimeUnit.SECONDS);
if (res) {
try {

} finally {
multiLock.unlock();
}
}
Code example of Async interface usage:

RLock lock1 = redisson1.getLock(“lock1”);
RLock lock2 = redisson2.getLock(“lock2”);
RLock lock3 = redisson3.getLock(“lock3”);

RLock multiLock = anyRedisson.getMultiLock(lock1, lock2, lock3);

RFuture lockFuture = multiLock.lockAsync();

// or acquire lock and automatically unlock it after 10 seconds
RFuture lockFuture = multiLock.lockAsync(10, TimeUnit.SECONDS);

// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
RFuture lockFuture = multiLock.tryLockAsync(100, 10, TimeUnit.SECONDS);

lockFuture.whenComplete((res, exception) -> {
// …
multiLock.unlockAsync();
});
Code example of Reactive interface usage:

RedissonReactiveClient anyRedisson = Redisson.createReactive(config);

RLockReactive lock1 = redisson1.getLock(“lock1”);
RLockReactive lock2 = redisson2.getLock(“lock2”);
RLockReactive lock3 = redisson3.getLock(“lock3”);

RLockReactive multiLock = anyRedisson.getMultiLock(lock1, lock2, lock3);

Mono lockMono = multiLock.lock();

// or acquire lock and automatically unlock it after 10 seconds
Mono lockMono = multiLock.lock(10, TimeUnit.SECONDS);

// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
Mono lockMono = multiLock.tryLock(100, 10, TimeUnit.SECONDS);

lockMono.doOnNext(res -> {
// …
})
.doFinally(multiLock.unlock())
.subscribe();
Code example of RxJava2 interface usage:

RedissonRxClient anyRedisson = Redisson.createRx(config);

RLockRx lock1 = redisson1.getLock(“lock1”);
RLockRx lock2 = redisson2.getLock(“lock2”);
RLockRx lock3 = redisson3.getLock(“lock3”);

RLockRx multiLock = anyRedisson.getMultiLock(lock1, lock2, lock3);

Completable lockRes = multiLock.lock();

// or acquire lock and automatically unlock it after 10 seconds
Completable lockRes = multiLock.lock(10, TimeUnit.SECONDS);

// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
Single lockRes = multiLock.tryLock(100, 10, TimeUnit.SECONDS);

lockRes.doOnSuccess(res -> {
// …
})
.doFinally(multiLock.unlock())
.subscribe();
4. RedLock
This object is deprecated. RLock operations now propagated to all Redis slaves.

  1. ReadWriteLock
    Redis based distributed reentrant ReadWriteLock object for Java implements java.util.concurrent.locks.ReadWriteLock interface. Both Read and Write locks implement RLock interface.

Multiple ReadLock owners and only one WriteLock owner are allowed.

If Redisson instance which acquired lock crashes then such lock could hang forever in acquired state. To avoid this Redisson maintains lock watchdog, it prolongs lock expiration while lock holder Redisson instance is alive. By default lock watchdog timeout is 30 seconds and can be changed through Config.lockWatchdogTimeout setting.

Also Redisson allow to specify leaseTime parameter during lock acquisition. After specified time interval locked lock will be released automatically.

RLock object behaves according to the Java Lock specification. It means only lock owner thread can unlock it otherwise IllegalMonitorStateException would be thrown. Otherwise consider to use RSemaphore object.

Code example:

RReadWriteLock rwlock = redisson.getReadWriteLock(“myLock”);

RLock lock = rwlock.readLock();
// or
RLock lock = rwlock.writeLock();

// traditional lock method
lock.lock();

// or acquire lock and automatically unlock it after 10 seconds
lock.lock(10, TimeUnit.SECONDS);

// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS);
if (res) {
try {

} finally {
lock.unlock();
}
}
Code example of Async interface usage:

RReadWriteLock rwlock = redisson.getReadWriteLock(“myLock”);

RLock lock = rwlock.readLock();
// or
RLock lock = rwlock.writeLock();

RFuture lockFuture = lock.lockAsync();

// or acquire lock and automatically unlock it after 10 seconds
RFuture lockFuture = lock.lockAsync(10, TimeUnit.SECONDS);

// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
RFuture lockFuture = lock.tryLockAsync(100, 10, TimeUnit.SECONDS);

lockFuture.whenComplete((res, exception) -> {

// ...

lock.unlockAsync();

});
Code example of Reactive interface usage:

RedissonReactiveClient redisson = Redisson.createReactive(config);

RReadWriteLockReactive rwlock = redisson.getReadWriteLock(“myLock”);

RLockReactive lock = rwlock.readLock();
// or
RLockReactive lock = rwlock.writeLock();

Mono lockMono = lock.lock();

// or acquire lock and automatically unlock it after 10 seconds
Mono lockMono = lock.lock(10, TimeUnit.SECONDS);

// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
Mono lockMono = lock.tryLock(100, 10, TimeUnit.SECONDS);

lockMono.doOnNext(res -> {
// …
})
.doFinally(lock.unlock())
.subscribe();
Code example of RxJava2 interface usage:

RedissonRxClient redisson = Redisson.createRx(config);

RReadWriteLockRx rwlock = redisson.getReadWriteLock(“myLock”);

RLockRx lock = rwlock.readLock();
// or
RLockRx lock = rwlock.writeLock();

Completable lockRes = lock.lock();

// or acquire lock and automatically unlock it after 10 seconds
Completable lockRes = lock.lock(10, TimeUnit.SECONDS);

// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
Single lockRes = lock.tryLock(100, 10, TimeUnit.SECONDS);

lockRes.doOnSuccess(res -> {
// …
})
.doFinally(lock.unlock())
.subscribe();
6. Semaphore
Redis based distributed Semaphore object for Java similar to java.util.concurrent.Semaphore object.

Could be initialized before usage, but it’s not requirement, with available permits amount through trySetPermits(permits) method.

Code example:

RSemaphore semaphore = redisson.getSemaphore(“mySemaphore”);

// acquire single permit
semaphore.acquire();

// or acquire 10 permits
semaphore.acquire(10);

// or try to acquire permit
boolean res = semaphore.tryAcquire();

// or try to acquire permit or wait up to 15 seconds
boolean res = semaphore.tryAcquire(15, TimeUnit.SECONDS);

// or try to acquire 10 permit
boolean res = semaphore.tryAcquire(10);

// or try to acquire 10 permits or wait up to 15 seconds
boolean res = semaphore.tryAcquire(10, 15, TimeUnit.SECONDS);
if (res) {
try {

} finally {
semaphore.release();
}
}
Code example of Async interface usage:

RSemaphore semaphore = redisson.getSemaphore(“mySemaphore”);

// acquire single permit
RFuture acquireFuture = semaphore.acquireAsync();

// or acquire 10 permits
RFuture acquireFuture = semaphore.acquireAsync(10);

// or try to acquire permit
RFuture acquireFuture = semaphore.tryAcquireAsync();

// or try to acquire permit or wait up to 15 seconds
RFuture acquireFuture = semaphore.tryAcquireAsync(15, TimeUnit.SECONDS);

// or try to acquire 10 permit
RFuture acquireFuture = semaphore.tryAcquireAsync(10);

// or try to acquire 10 permits or wait up to 15 seconds
RFuture acquireFuture = semaphore.tryAcquireAsync(10, 15, TimeUnit.SECONDS);

acquireFuture.whenComplete((res, exception) -> {
// …
semaphore.releaseAsync();
});
Code example of Reactive interface usage:

RedissonReactiveClient redisson = Redisson.createReactive(config);

RSemaphoreReactive semaphore = redisson.getSemaphore(“mySemaphore”);

// acquire single permit
Mono acquireMono = semaphore.acquire();

// or acquire 10 permits
Mono acquireMono = semaphore.acquire(10);

// or try to acquire permit
Mono acquireMono = semaphore.tryAcquire();

// or try to acquire permit or wait up to 15 seconds
Mono acquireMono = semaphore.tryAcquire(15, TimeUnit.SECONDS);

// or try to acquire 10 permit
Mono acquireMono = semaphore.tryAcquire(10);

// or try to acquire 10 permits or wait up to 15 seconds
Mono acquireMono = semaphore.tryAcquire(10, 15, TimeUnit.SECONDS);

acquireMono.doOnNext(res -> {
// …
})
.doFinally(semaphore.release())
.subscribe();
Code example of RxJava2 interface usage:

RedissonRxClient redisson = Redisson.createRx(config);

RSemaphoreRx semaphore = redisson.getSemaphore(“mySemaphore”);

// acquire single permit
Completable acquireRx = semaphore.acquire();

// or acquire 10 permits
Completable acquireRx = semaphore.acquire(10);

// or try to acquire permit
Single acquireRx = semaphore.tryAcquire();

// or try to acquire permit or wait up to 15 seconds
Single acquireRx = semaphore.tryAcquire(15, TimeUnit.SECONDS);

// or try to acquire 10 permit
Single acquireRx = semaphore.tryAcquire(10);

// or try to acquire 10 permits or wait up to 15 seconds
Single acquireRx = semaphore.tryAcquire(10, 15, TimeUnit.SECONDS);

acquireRx.doOnSuccess(res -> {
// …
})
.doFinally(semaphore.release())
.subscribe();
7. PermitExpirableSemaphore
Redis based distributed Semaphore object for Java with lease time parameter support for each acquired permit. Each permit identified by own id and could be released only using its id.

Should be initialized before usage with available permits amount through trySetPermits(permits) method. Allows to increase/decrease number of available permits through addPermits(permits) method.

Code example:

RPermitExpirableSemaphore semaphore = redisson.getPermitExpirableSemaphore(“mySemaphore”);

semaphore.trySetPermits(23);

// acquire permit
String id = semaphore.acquire();

// or acquire permit with lease time in 10 seconds
String id = semaphore.acquire(10, TimeUnit.SECONDS);

// or try to acquire permit
String id = semaphore.tryAcquire();

// or try to acquire permit or wait up to 15 seconds
String id = semaphore.tryAcquire(15, TimeUnit.SECONDS);

// or try to acquire permit with least time 15 seconds or wait up to 10 seconds
String id = semaphore.tryAcquire(10, 15, TimeUnit.SECONDS);
if (id != null) {
try {

} finally {
semaphore.release(id);
}
}
Code example of Async interface usage:

RPermitExpirableSemaphore semaphore = redisson.getPermitExpirableSemaphore(“mySemaphore”);

RFuture setFuture = semaphore.trySetPermitsAsync(23);

// acquire permit
RFuture acquireFuture = semaphore.acquireAsync();

// or acquire permit with lease time in 10 seconds
RFuture acquireFuture = semaphore.acquireAsync(10, TimeUnit.SECONDS);

// or try to acquire permit
RFuture acquireFuture = semaphore.tryAcquireAsync();

// or try to acquire permit or wait up to 15 seconds
RFuture acquireFuture = semaphore.tryAcquireAsync(15, TimeUnit.SECONDS);

// or try to acquire permit with least time 15 seconds or wait up to 10 seconds
RFuture acquireFuture = semaphore.tryAcquireAsync(10, 15, TimeUnit.SECONDS);
acquireFuture.whenComplete((id, exception) -> {
// …
semaphore.releaseAsync(id);
});
Code example of Reactive interface usage:

RedissonReactiveClient redisson = Redisson.createReactive(config);

RPermitExpirableSemaphoreReactive semaphore = redisson.getPermitExpirableSemaphore(“mySemaphore”);

Mono setMono = semaphore.trySetPermits(23);

// acquire permit
Mono acquireMono = semaphore.acquire();

// or acquire permit with lease time in 10 seconds
Mono acquireMono = semaphore.acquire(10, TimeUnit.SECONDS);

// or try to acquire permit
Mono acquireMono = semaphore.tryAcquire();

// or try to acquire permit or wait up to 15 seconds
Mono acquireMono = semaphore.tryAcquire(15, TimeUnit.SECONDS);

// or try to acquire permit with least time 15 seconds or wait up to 10 seconds
Mono acquireMono = semaphore.tryAcquire(10, 15, TimeUnit.SECONDS);

acquireMono.flatMap(id -> {
// …
return semaphore.release(id);
}).subscribe();
Code example of RxJava2 interface usage:

RedissonRxClient redisson = Redisson.createRx(config);

RPermitExpirableSemaphoreRx semaphore = redisson.getPermitExpirableSemaphore(“mySemaphore”);

Single setRx = semaphore.trySetPermits(23);

// acquire permit
Single acquireRx = semaphore.acquire();

// or acquire permit with lease time in 10 seconds
Single acquireRx = semaphore.acquire(10, TimeUnit.SECONDS);

// or try to acquire permit
Maybe acquireRx = semaphore.tryAcquire();

// or try to acquire permit or wait up to 15 seconds
Maybe acquireRx = semaphore.tryAcquire(15, TimeUnit.SECONDS);

// or try to acquire permit with least time 15 seconds or wait up to 10 seconds
Maybe acquireRx = semaphore.tryAcquire(10, 15, TimeUnit.SECONDS);

acquireRx.flatMap(id -> {
// …
return semaphore.release(id);
}).subscribe();
8. CountDownLatch
Redis based distributed CountDownLatch object for Java has structure similar to java.util.concurrent.CountDownLatch object.

Should be initialized with count by trySetCount(count) method before usage.

Code example:

RCountDownLatch latch = redisson.getCountDownLatch(“myCountDownLatch”);

latch.trySetCount(1);
// await for count down
latch.await();

// in other thread or JVM
RCountDownLatch latch = redisson.getCountDownLatch(“myCountDownLatch”);
latch.countDown();
Code example of Async interface usage:

RCountDownLatch latch = redisson.getCountDownLatch(“myCountDownLatch”);

RFuture setFuture = lock.trySetCountAsync(1);
// await for count down
RFuture awaitFuture = latch.awaitAsync();

// in other thread or JVM
RCountDownLatch latch = redisson.getCountDownLatch(“myCountDownLatch”);
RFuture countFuture = latch.countDownAsync();
Code example of Reactive interface usage:

RedissonReactiveClient redisson = Redisson.createReactive(config);
RCountDownLatchReactive latch = redisson.getCountDownLatch(“myCountDownLatch”);

Mono setMono = latch.trySetCount(1);
// await for count down
Mono awaitMono = latch.await();

// in other thread or JVM
RCountDownLatchReactive latch = redisson.getCountDownLatch(“myCountDownLatch”);
Mono countMono = latch.countDown();
Code example of RxJava2 interface usage:

RedissonRxClient redisson = Redisson.createRx(config);
RCountDownLatchRx latch = redisson.getCountDownLatch(“myCountDownLatch”);

Single setRx = latch.trySetCount(1);
// await for count down
Completable awaitRx = latch.await();

// in other thread or JVM
RCountDownLatchRx latch = redisson.getCountDownLatch(“myCountDownLatch”);
Completable countRx = latch.countDown();

org.redisson redisson-spring-boot-starter 3.13.1
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: