Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Redis-Based Distributed Java Semaphores With Redisson

DZone's Guide to

Redis-Based Distributed Java Semaphores With Redisson

We take a look under the hood of this interesting open source database and see how ti uses Java methods to make distributed semaphores possible.

· Database Zone ·
Free Resource

Read the 2019 State of Database DevOps Report for the very latest insights

A semaphore is an entity that controls how many processes can access the same resource concurrently. Locks can be thought of as a special type of semaphore with an upper limit of 1 process.

Semaphores allow access to a resource by giving permits to a process. The process must first acquire a permit, and then release it once it is no longer needed. The semaphor maintains an internal counter to keep track of how many permits remain.

Because semaphores are a crucial part of distributed and parallel computing, it’s no surprise that you can build semaphores in Redis. However, building a correctly-working Redis-based semaphore on Java all by yourself can be difficult and time-consuming (as you’ll see if you check out that link).

The good news is that you can use Redisson: a framework for distributed programming with Redis and Java that already contains implementations of semaphores and related concepts (such as the CountDownLatch).

Below, we’ll discuss three essential objects for distributed programming in Redis—RSemaphore, RPermitExpirableSemaphore, and RCountDownLatch—and the right situation to use each one.

Semaphore

The RSemaphore object in Redisson is similar to the java.util.concurrent.Semaphore class in plain Java. The acquire() method is used to acquire a permit from the semaphore, and the release() method is used to release a permit that is no longer needed.

In the event that no permit is available, the acquire() method blocks the thread until one is available or the thread is interrupted. The tryAcquire() method attempts to acquire a permit for a specified amount of time (e.g. 23 seconds in the example code below):

RSemaphore semaphore = redisson.getSemaphore("semaphore");
semaphore.acquire();
//try to acquire in 23 seconds
semaphore.tryAcquire(23, TimeUnit.SECONDS);

// ...

semaphore.release();

The RSemaphore object comes with three different interfaces that you can use: Async, Reactive, and RxJava2.

PermitExpirableSemaphore

The RPermitExpirableSemaphore object in Redisson is used for semaphores whose permits can be acquired with an (optional) time limit. Each permit is identified by a unique ID and can only be released using this ID.

In the example code below, we attempt to acquire two permits from the semaphore: one with no time limit, and one with a time limit of 2 seconds.

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

The RPermitExpirableSemaphore object comes with three different interfaces that you can use: Async, Reactive, and RxJava2.

CountDownLatch

The RCountDownLatch object in Redisson is similar to the java.util.concurrent.CountDownLatch class in plain Java. In Java, a CountDownLatch is used to ensure that a thread waits until another thread or threads complete a set of operations. This is slightly different from the purpose of a Semaphore, which is used to control the number of threads that are concurrently accessing a resource.

In this example code, the first thread waits for another thread to finish using the await() method:

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

Meanwhile, in another thread or another Java virtual machine uses the same Redis setup through Redisson, the countDown() method is used to decrement the counter of the CountDownLatch:

RCountDownLatch latch = redisson.getCountDownLatch("anyCountDownLatch");
latch.countDown();

After the countDown() method is called, the first thread should be able to access the resource.

Read the 2019 State of Database DevOps Report for latest insights into DevOps adoption among SQL Server professionals, and the benefits and challenges of including the database in DevOps initiatives

Topics:
redis ,distributed system ,database ,open source databases

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}