Distributed locks and synchronizers

Nikita Koksharov edited this page on 18 Jan · ​​50 revisions​

8.1. Lock

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<Void> lockFuture = lock.lockAsync();

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

// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
RFuture<Boolean> 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<Void> lockMono = lock.lock();

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

// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
Mono<Boolean> 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<Boolean> lockRes = lock.tryLock(100, 10, TimeUnit.SECONDS);

lockRes.doOnSuccess(res -> {
// ...
})
.doFinally(lock.unlock())
.subscribe();

8.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<Void> lockFuture = lock.lockAsync();

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

// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
RFuture<Boolean> 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<Void> lockMono = lock.lock();

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

// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
Mono<Boolean> 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<Boolean> lockRes = lock.tryLock(100, 10, TimeUnit.SECONDS);

lockRes.doOnSuccess(res -> {
// ...
})
.doFinally(lock.unlock())
.subscribe();

8.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<Void> lockFuture = multiLock.lockAsync();

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

// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
RFuture<Boolean> 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<Void> lockMono = multiLock.lock();

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

// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
Mono<Boolean> 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<Boolean> lockRes = multiLock.tryLock(100, 10, TimeUnit.SECONDS);

lockRes.doOnSuccess(res -> {
// ...
})
.doFinally(multiLock.unlock())
.subscribe();

8.4. RedLock

Redis based distributed ​​RedLock​​​ object for Java implements ​​Redlock​​​ locking algorithm. It groups multiple ​​RLock​​​ objects and handles them as one lock. Each ​​RLock​​ object may belong to different Redisson instances.

If Redisson instance which acquired ​​RedLock​​​ crashes then such ​​RedLock​​​ 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.

​RedLock​​​ 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 redLock = anyRedisson.getRedLock(lock1, lock2, lock3);

// traditional lock method
redLock.lock();

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

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

Code example of ​​Async​​ interface​ usage:

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

RLock redLock = anyRedisson.getRedLock(lock1, lock2, lock3);

RFuture<Void> lockFuture = redLock.lockAsync();

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

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

lockFuture.whenComplete((res, exception) -> {
// ...
redLock.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 redLock = anyRedisson.getRedLock(lock1, lock2, lock3);

Mono<Void> lockMono = redLock.lock();

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

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

lockMono.doOnNext(res -> {
// ...
})
.doFinally(redLock.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 redLock = anyRedisson.getRedLock(lock1, lock2, lock3);

Completable lockRes = redLock.lock();

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

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

lockRes.doOnSuccess(res -> {
// ...
})
.doFinally(redLock.unlock())
.subscribe();

8.5. 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<Void> lockFuture = lock.lockAsync();

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

// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
RFuture<Boolean> 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<Void> lockMono = lock.lock();

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

// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
Mono<Boolean> 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<Boolean> lockRes = lock.tryLock(100, 10, TimeUnit.SECONDS);

lockRes.doOnSuccess(res -> {
// ...
})
.doFinally(lock.unlock())
.subscribe();

8.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<Void> acquireFuture = semaphore.acquireAsync();

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

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

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

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

// or try to acquire 10 permits or wait up to 15 seconds
RFuture<Boolean> 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<Void> acquireMono = semaphore.acquire();

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

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

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

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

// or try to acquire 10 permits or wait up to 15 seconds
Mono<Boolean> 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<Boolean> acquireRx = semaphore.tryAcquire();

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

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

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

acquireRx.doOnSuccess(res -> {
// ...
})
.doFinally(semaphore.release())
.subscribe();

8.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<Boolean> setFuture = semaphore.trySetPermitsAsync(23);

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

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

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

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

// or try to acquire permit with least time 15 seconds or wait up to 10 seconds
RFuture<String> 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<Boolean> setMono = semaphore.trySetPermits(23);

// acquire permit
Mono<String> acquireMono = semaphore.acquire();

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

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

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

// or try to acquire permit with least time 15 seconds or wait up to 10 seconds
Mono<String> 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<Boolean> setRx = semaphore.trySetPermits(23);

// acquire permit
Single<String> acquireRx = semaphore.acquire();

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

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

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

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

acquireRx.flatMap(id -> {
// ...
return semaphore.release(id);
}).subscribe();

8.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<Boolean> setFuture = lock.trySetCountAsync(1);
// await for count down
RFuture<Void> awaitFuture = latch.awaitAsync();

// in other thread or JVM
RCountDownLatch latch = redisson.getCountDownLatch("myCountDownLatch");
RFuture<Void> countFuture = latch.countDownAsync();

Code example of ​​Reactive​​ interface​ usage:

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

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

// in other thread or JVM
RCountDownLatchReactive latch = redisson.getCountDownLatch("myCountDownLatch");
Mono<Void> countMono = latch.countDown();

Code example of ​​RxJava2​​ interface​ usage:

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

Single<Boolean> 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();