8. Distributed locks and synchronizers

Nikita Koksharov edited this page Sep 9, 2016 · 10 revisions

8.1. Lock

Redisson distributed reentrant Lock for Java implements java.util.concurrent.locks.Lock interface and supports TTL.

RLock lock = redisson.getLock("anyLock");
// Most familiar locking method
lock.lock();

// Lock time-to-live support
// releases lock automatically after 10 seconds
// if unlock method not invoked
lock.lock(10, TimeUnit.SECONDS);

// Wait for 100 seconds and automatically unlock it after 10 seconds
boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS);
...
lock.unlock();

Redisson also provides an asynchronous methods for Lock object:

RLock lock = redisson.getLock("anyLock");
lock.lockAsync();
lock.lockAsync(10, TimeUnit.SECONDS);
Future<Boolean> res = lock.tryLockAsync(100, 10, TimeUnit.SECONDS);

RLock objects behave according java Lock specification. It means only lock owner thread can unlock it otherwise IllegalMonitorStateException would be thrown. But if you still need such scenario use RSemaphore object.

8.2. Fair Lock

Redisson distributed reentrant fair Lock for Java implements java.util.concurrent.locks.Lock interface and supports TTL and guarantees that Redisson client threads will acquire it in is same order they requested it. It has same interface as simple Lock object.

RLock fairLock = redisson.getFairLock("anyLock");
// Most familiar locking method
fairLock.lock();

// Lock time-to-live support
// releases lock automatically after 10 seconds
// if unlock method not invoked
fairLock.lock(10, TimeUnit.SECONDS);

// Wait for 100 seconds and automatically unlock it after 10 seconds
boolean res = fairLock.tryLock(100, 10, TimeUnit.SECONDS);
...
fairLock.unlock();

Redisson also provides an asynchronous methods for fair Lock object:

RLock fairLock = redisson.getFairLock("anyLock");
fairLock.lockAsync();
fairLock.lockAsync(10, TimeUnit.SECONDS);
Future<Boolean> res = fairLock.tryLockAsync(100, 10, TimeUnit.SECONDS);

8.3. MultiLock

RedissonMultiLock object groups multiple RLock objects and handles them as one lock. Each RLock object may belong to different Redisson instances.

RLock lock1 = redissonInstance1.getLock("lock1");
RLock lock2 = redissonInstance2.getLock("lock2");
RLock lock3 = redissonInstance3.getLock("lock3");

RedissonMultiLock lock = new RedissonMultiLock(lock1, lock2, lock3);
// locks: lock1 lock2 lock3
lock.lock();
...
lock.unlock();

8.4. RedLock

RedissonRedLock object implements Redlock locking algorithm. It groups multiple RLock objects and handles them as one lock. Each RLock object may belong to different Redisson instances.

RLock lock1 = redissonInstance1.getLock("lock1");
RLock lock2 = redissonInstance2.getLock("lock2");
RLock lock3 = redissonInstance3.getLock("lock3");

RedissonRedLock lock = new RedissonRedLock(lock1, lock2, lock3);
// locks: lock1 lock2 lock3
lock.lock();
...
lock.unlock();

8.5. ReadWriteLock

Redisson distributed reentrant ReadWriteLock object for Java implements java.util.concurrent.locks.ReadWriteLock interface and supports TTL. Many ReadLock owners and only one WriteLock owner are allowed.

RReadWriteLock rwlock = redisson.getLock("anyRWLock");
// Most familiar locking method
rwlock.readLock().lock();
// or
rwlock.writeLock().lock();

// Lock time-to-live support
// releases lock automatically after 10 seconds
// if unlock method not invoked
rwlock.readLock().lock(10, TimeUnit.SECONDS);
// or
rwlock.writeLock().lock(10, TimeUnit.SECONDS);

// Wait for 100 seconds and automatically unlock it after 10 seconds
boolean res = rwlock.readLock().tryLock(100, 10, TimeUnit.SECONDS);
// or
boolean res = rwlock.writeLock().tryLock(100, 10, TimeUnit.SECONDS);
...
lock.unlock();

8.6. Semaphore

Redisson distributed Semaphore object for Java similar to java.util.concurrent.Semaphore object.

RSemaphore semaphore = redisson.getSemaphore("semaphore");
semaphore.acquire();
//or
semaphore.acquireAsync();
semaphore.acquire(23);
semaphore.tryAcquire();
//or
semaphore.tryAcquireAsync();
semaphore.tryAcquire(23, TimeUnit.SECONDS);
//or
semaphore.tryAcquireAsync(23, TimeUnit.SECONDS);
semaphore.release(10);
semaphore.release();
//or
semaphore.releaseAsync();

8.7. PermitExpirableSemaphore

Semaphore object with lease time parameter support for each acquired permit. Each permit identified by own id and could be released only using its id.

RPermitExpirableSemaphore semaphore = redisson.getPermitExpirableSemaphore("mySemaphore");
String permitId = semaphore.acquire();
// acquire permit with lease time = 2 seconds
String permitId = semaphore.acquire(2, TimeUnit.SECONDS);
// ...
semaphore.release(permitId);

8.8. CountDownLatch

Redisson distributed CountDownLatch object for Java has structure similar to java.util.concurrent.CountDownLatch object.

RCountDownLatch latch = redisson.getCountDownLatch("anyCountDownLatch");
latch.trySetCount(1);
latch.await();

// in other thread or other JVM
RCountDownLatch latch = redisson.getCountDownLatch("anyCountDownLatch");
latch.countDown();