Distributed Java Collections in Redis With Redisson
In this article, we go over an interesting open source database project and how it takes advantage of core principles of the Java language,.
Join the DZone community and get the full member experience.
Join For FreeWhat Are Distributed Collections?
In Java, a Collection is a term for any group of objects, which are known as the elements of the Collection. The Collection interface describes a general formula for how to implement a specific type of collection. Some examples of collections in Java are:
● Map
● Set
● List
● SortedSet
● SortedMap
When working with a multithreaded program, it’s important to make sure that different threads do not access the same collection at the same time. When this occurs, it can result in race conditions, bugs, and other unanticipated behavior.
In order to address these issues, programmers use Redisson and other distributed frameworks. Redisson is a Java framework which provides distributed objects and services on top of the Redis server. It allows multiple threads to concurrently access the same collection in Redis.
Java Collections in Redis for Redisson
Redisson provides implementations of many different distributed collections in Java for Redis. These distributed collections can be shared across more than one thread, and even in multiple JVMs.
Below, we’ll discuss the different options for distributed collections in Redis with Redisson, and the right time to use each one.
Map
The RMap object in Redisson implements the java.util.concurrent.ConcurrentMap and java.util.Map interfaces. A Map is a collection of key-value pairs in which keys cannot be duplicated. This implementation preserves elements in their order of insertion. Below is the usage example:
RMap<String, SomeObject> map = redisson.getMap("anyMap");
SomeObject prevObject = map.put("123", new SomeObject());
SomeObject currentObject = map.putIfAbsent("323", new SomeObject());
SomeObject obj = map.remove("123")
As the example code below demonstrates, you can associate a Lock/ReadWriteLock/Semaphore/CountDownLatch object with each element in an RMap:
RMap<MyKey, MyValue> map = redisson.getMap("anyMap");
MyKey k = new MyKey();
RLock keyLock = map.getLock(k);
keyLock.lock();
try {
MyValue v = map.get(k);
// process value ...
} finally {
keyLock.unlock();
}
In addition to the generic Map, Redisson provides support for Redis-based Maps that can have three different important features:
● Local caching: useful when you will be reading the Map many times.
● Data partitioning: maximizes the Map’s use of the available memory.
● Eviction: allows you to define the lifetime of each element in the Map.
Multimap
The Multimap object in Redisson implements a multimap collection in Java. Multimaps are maps that can store the same key multiple times.
Redisson includes both a Set-based Multimap (RSetMultimap) and a-List based Multimap (RListMultimap). As the example code below demonstrates, the RListMultimap allows duplication of key-value pairs, while the RSetMultimap does not:
RListMultimap<SimpleKey, SimpleValue> map = redisson.getListMultimap("test1");
map.put(new SimpleKey("0"), new SimpleValue("1"));
map.put(new SimpleKey("0"), new SimpleValue("2"));
map.put(new SimpleKey("0"), new SimpleValue("1"));
map.put(new SimpleKey("3"), new SimpleValue("4"));
List<SimpleValue> allValues = map.get(new SimpleKey("0"));
Collection<SimpleValue> newValues = Arrays.asList(new SimpleValue("7"), new SimpleValue("6"), new SimpleValue("5"));
List<SimpleValue> oldValues = map.replaceValues(new SimpleKey("0"), newValues);
List<SimpleValue> removedValues = map.removeAll(new SimpleKey("0"));
The MultimapCache object in Redisson provides support for cache eviction. Like the Multimap object, it comes in both RSetMultimapCache and RListMultimapCache options:
RSetMultimapCache<String, String> multimap = redisson.getSetMultimapCache("myMultimap");
multimap.put("1", "a");
multimap.put("1", "b");
multimap.put("1", "c");
multimap.put("2", "e");
multimap.put("2", "f");
multimap.expireKey("2", 10, TimeUnit.MINUTES);
Set
The RSet interface in Redisson implements the java.util.Set interface in Java.
The example code below creates an RSet object, and then adds and removes
an element:
RSet<SomeObject> set = redisson.getSet("anySet");
set.add(new SomeObject());
set.remove(new SomeObject());
As the example code below demonstrates, you can associate a Lock/ReadWriteLock/Semaphore/CountDownLatch object with each element in an RSet:
RSet<MyObject> set = redisson.getSet("anySet");
MyObject value = new MyObject();
RLock lock = set.getLock(value);
lock.lock();
try {
// process value ...
} finally {
lock.unlock();
}
In addition to the generic Set, Redisson provides Redis with support for Sets that have important features:
● Data partitioning: data partitioning in Redisson maximizes the Set’s use of the available memory.
● Eviction: allows you to define the lifetime of each element in the Set.
List
The RList interface in Redisson implements the java.util.List interface in Java. Like the original List in Java, Lists in Redisson preserve elements in the order that they were inserted.
The example code below creates an RList object, and then adds and removes an element:
RList<SomeObject> list = redisson.getList("anyList");
list.add(new SomeObject());
list.get(0);
list.remove(new SomeObject());
SortedSet
The RSortedSet interface in Redisson implements the java.util.SortedSet interface in Java. It requires a Comparator comparison function in order to sort elements and preserve their uniqueness.
The example code below creates an RSortedSet object together with a Comparator function, and then inserts several elements together with their scores:
RSortedSet<Integer> set = redisson.getSortedSet("anySet");
set.trySetComparator(new MyComparator()); // set object comparator
set.add(3);
set.add(1);
set.add(2);
set.removeAsync(0);
set.addAsync(5);
ScoredSortedSet
The RScoredSortedSet interface in Redisson is used to sort elements by a score that is defined during the process of element insertion. The uniqueness of elements is preserved via state comparison.
The example code below creates an RScoredSortedSet object and inserts several elements together with their scores:
RScoredSortedSet<SomeObject> set = redisson.getScoredSortedSet("simple");
set.add(0.13, new SomeObject(a, b));
set.addAsync(0.251, new SomeObject(c, d));
set.add(0.302, new SomeObject(g, d));
set.pollFirst();
set.pollLast();
Opinions expressed by DZone contributors are their own.
Comments