In this post, we will compare and contrast ConcurrentSkipListSet and Collections.SynchronizedSet() in Java that are used to implement a synchronized set in Java.

1. Overview of ConcurrentSkipListSet

ConcurrentSkipListSet is a class that implements the Set and NavigableSet interfaces and uses a concurrent skip list as its underlying data structure to store elements. A concurrent skip list is a probabilistic data structure that consists of multiple linked lists arranged in a hierarchy. The elements in a concurrent skip list are sorted by default in their natural ordering or by a Comparator provided at set creation time, depending on which constructor is used. It offers many benefits:

  • ConcurrentSkipListSet allows safe execution of insertion, removal, and access operations on set concurrently by multiple threads. It should be preferred over other Set interface implementations when concurrent modification of set by multiple threads is required.
  • ConcurrentSkipListSet does not lock the entire set, but only parts of it, allowing parallel access for multiple threads. This means that multiple threads can access the set at the same time without blocking each other, which improves the performance.
  • ConcurrentSkipListSet does not allow null elements in the set. This means that we cannot insert null values in a ConcurrentSkipListSet without throwing an exception.
  • ConcurrentSkipListSet preserves the order of the elements in the set. This means that we can iterate over the elements in a ConcurrentSkipListSet in a sorted order according to their natural ordering or by a provided Comparator.
  • ConcurrentSkipListSet provides additional methods to navigate the set in a sorted order, such as first(), last(), lower(), higher(), etc. These methods allow us to access the first or last element in the set, or find an element that is less than or greater than a given element.

Let’s see an example of how to create and use a ConcurrentSkipListSet in Java:

Download  Run Code

2. Overview of Collections.SynchronizedSet() method

The Collections.synchronizedSet() is a static method of the Collections class that returns a synchronized or thread-safe set backed by the specified set. This method is used to create a synchronized wrapper around an existing set, such as HashSet, TreeSet, or LinkedHashSet. It offers some benefits over ConcurrentSkipListSet:

  • SynchronizedSet() locks the entire set, blocking parallel access for multiple threads. This means that only one thread can access the set at a time, which ensures data consistency and prevents concurrency issues.
  • SynchronizedSet() allows null elements in the set, only if the backing set does. This means that we can insert null values in a SynchronizedSet() if the backing set allows it.
  • SynchronizedSet() does not preserve the order of the elements in the set, unless the backing set does. This means that the order of the elements in a SynchronizedSet() depends on the type of the backing set. If HashSet is used as the backing set, the order of the elements is undefined. If TreeSet is used as the backing set, the order of the elements is the same as the natural ordering of its elements or that of a provided Comparator. If LinkedHashSet is used as the backing set, the order of the elements is the same as their insertion order.
  • SynchronizedSet() does not provide any additional methods to navigate the set in a sorted order, unless the backing set does. This means that we cannot access the first or last element in the set, or find an element that is less than or greater than a given element, unless we use a TreeSet as the backing set.

Let’s see an example of how to create and use a SynchronizedSet() in Java:

Download  Run Code

3. Differences between ConcurrentSkipListSet and Collections.SynchronizedSet()

Here are some of the main differences between ConcurrentSkipListSet and Collections.SynchronizedSet() in Java:

  • ConcurrentSkipListSet is a class that implements Set and NavigableSet interfaces, while SynchronizedSet() is a method of Collections class that returns a Set interface.
  • ConcurrentSkipListSet uses a concurrent skip list as its underlying data structure, while SynchronizedSet() uses any type of set as its underlying data structure.
  • ConcurrentSkipListSet allows parallel access for multiple threads without blocking them, while SynchronizedSet() blocks parallel access for multiple threads and allows only one thread to access the set at a time.
  • ConcurrentSkipListSet does not allow null elements in the set, while SynchronizedSet() allows null elements in the set depending on the backing set.
  • ConcurrentSkipListSet preserves the order of the elements in the set according to their natural ordering or by a provided Comparator, while SynchronizedSet() does not preserve the order of the elements in the set unless the backing set does.
  • ConcurrentSkipListSet provides additional methods to navigate the set in a sorted order, such as first, last, lower, higher, etc., while SynchronizedSet() does not provide any additional methods to navigate the set in a sorted order unless the backing set does.
  • ConcurrentSkipListSet iterator is weakly consistent, which never throws ConcurrentModificationException even if the set is modified after the construction of the iterator. On the contrary, SynchronizedSet() does not guarantee a fail-safe iterator on concurrent modification. The fail-safe or fail-fast behavior totally depends on the backing set.

4. Choosing between ConcurrentSkipListSet and Collections.SynchronizedSet()

As we have seen, ConcurrentSkipListSet and Collections.SynchronizedSet() are both useful methods to create a synchronized or thread-safe set in Java. Here are some general recommendations on how to choose between them:

  • If you need to create a synchronized set that can be accessed concurrently by multiple threads without blocking them, we should use ConcurrentSkipListSet.
  • If you need to create a synchronized set that can be accessed safely by multiple threads with data consistency, we should use SynchronizedSet().
  • If you need to create a synchronized set that can meet our specific requirements, we can create our own implementation of Set or NavigableSet interface using appropriate synchronization techniques, such as locks, semaphores, or atomic variables.

That’s all about ConcurrentSkipListSet and Collections.SynchronizedSet() in Java.