Synchronized Collections in Java

Synchronized Collections in Java

There are various collection utilities available in Java to make our development easier but very few collection classes are synchronized in nature i.e thread-safe.  Thread-safety is considered to be a very important feature for multi-threaded applications.

First of all, let us understand why synchronized collection classes are required in Java.

Problems associated with non-synchronized collections

  • We know, Collection is a group of objects.
  • Consider a scenario, where thread-1 is storing set of value in an ArrayList – {BA,BB.BC,BD,BE} and thread-2 is removing the values from same ArrayList.
  • As ArrayList is non-synchronized , multiple thread can access the ArrayList at same time so thread-1 and thread-2 can perform their tasks on ArrayList at same time which will produce inconsistent results and unexpected errors.
  • This is synchronization problem associated with non-synchronized collections in java.
  • Learn more about Synchronization in Java.

Here is the list of Synchronized collections classes in Java

  1. Vector
  2. HashTable
  3. SynchronousQueue

Vector (Synchronized Collection in Java)

Java Vector class implements List interface. It is available in the java.util package. Vector class is synchronized in nature i.e. this is a thread-safe class.

Important points related to Vector class :

  • Vector is an implementing class of List interface.
  • It is considered to be very similar to ArrayList but it provides thread-safe objects.
  • Underlying data structure used in Vector class is dynamic array which means it can grow or shrink as required. Same as array, it contains data that can be accessed using an integer index.
  • Vector has some legacy method which collection framework does not contain.
  • Vector class extends AbstractList and implements List interfaces.

Example of Vector class :

import java.util.*;
public class VectorExample {

public static void main(String args[]) {

// initial size is 3, increment is 2
Vector vec = new Vector(3, 2);
System.out.println("Initial size: " + vec.size());
System.out.println("Initial capacity: " + vec.capacity());

vec.addElement(new Integer(1));
vec.addElement(new Integer(2));
vec.addElement(new Integer(3));
vec.addElement(new Integer(4));
System.out.println("Capacity after four additions: " + vec.capacity());

vec.addElement(new Double(5.45));
System.out.println("Current capacity: " + vec.capacity());

vec.addElement(new Double(6.08));
vec.addElement(new Integer(7));
System.out.println("Current capacity: " + vec.capacity());

vec.addElement(new Float(9.4));
vec.addElement(new Integer(10));
System.out.println("Current capacity: " + vec.capacity());

vec.addElement(new Integer(11));
vec.addElement(new Integer(12));
System.out.println("First element: " + (Integer)vec.firstElement());
System.out.println("Last element: " + (Integer)vec.lastElement());

if(vec.contains(new Integer(3)))
System.out.println("Vector contains 3.");

// enumerate the elements in the vector.
Enumeration vEnum = vec.elements();
System.out.println("\nElements in vector:");

while(vEnum.hasMoreElements())
System.out.print(vEnum.nextElement() + " ");
System.out.println();
}
}

Output:

Initial size: 0
Initial capacity: 3
Capacity after four additions: 5
Current capacity: 5
Current capacity: 7
Current capacity: 9
First element: 1
Last element: 12
Vector contains 3.

Elements in vector:
1 2 3 4 5.45 6.08 7 9.4 10 11 12

HashTable (Synchronized Collection in Java)

HashTable class in Java implements a hash table, It  maps keys to values. HashTable is thread-safe class. Similar to HashMap, it also stores the data in key,value pair.  The key is hashed using hashing functionality and the resulting hash code is used as the index at which the value is stored within the table.
To successfully store and retrieve objects from a hashtable, t

Important points to remember about HashTable in Java :

  • HashTable stores the data in key/value pair.
  • HashTable is a thread-safe class as it implements synchronization technique in its implementation.
  • Unlike HashMap, In HashTable null key / value is not allowed.
  • In Hashtable , hashing functionality is computed on key to find the address to store the value.

Example of HashTable :

import java.util.*;

class hashTableExample1 {

public static void main(String[] arg)
{

// code to create a hash table
Hashtable<Integer, String> ht =
new Hashtable<Integer, String>();

Hashtable<Integer, String> ht2 =
new Hashtable<Integer, String>();


ht.put(1, “Tech”);
ht.put(2, “Blog”);
ht.put(3, “Station”);


// code to create a clone or shallow copy of existing hashtable
ht2 = (Hashtable<Integer, String>)ht.clone();


System.out.println(“values present in clone: ” + ht2);


// code to clear hashtable
ht.clear();


System.out.println(“after clearing: ” + ht2);
}
}

Output:

values present in clone: {1=Tech, 2=Blog, 3=Station}
after clearing: {}

SynchronousQueue(Synchronized Collection in Java)

SynchronousQueue implements the BlockingQueue interface hence it is defined as a blocking queue . SynchronousQueue  is synchronized i.e. thread-safe.

Important points to remember about SynchronousQueue in Java :

  • Each insert operation in SynchronousQueue must wait for a corresponding remove operation by another thread, and also vice versa.
  • A synchronous queue does not have internal capacity.
  • You cannot do the peek operation at a synchronous queue because an element is only present  in it when you try to remove it; you also cannot insert an element  in it using any method unless another thread is trying to remove it.
  • The head of the queue is the element that the first queued inserting thread is trying to add to the queue; if there is no such queued thread then no element is available for removal and poll() will return null.

Example of Producer Consumer problem using SynchronousQueue in Java :

public class SynchronousQueueEx{

    public static void main(String args[]) {

        final SynchronousQueue<String> queue = new SynchronousQueue<String>();

        Thread producer = new Thread("PRODUCER") {
            public void run() {
                String event = "ONE";
                try {
                    queue.put(event); // thread will block here
                    System.out.printf("[%s] published event : %s %n", Thread
                            .currentThread().getName(), event);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        };

        producer.start(); // starting publisher thread

        Thread consumer = new Thread("CONSUMER") {
            public void run() {
                try {
                    String event = queue.take(); // thread will block here
                    System.out.printf("[%s] consumed event : %s %n", Thread
                            .currentThread().getName(), event);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        };

        consumer.start(); // starting consumer thread

    }

}

Output:

[CONSUMER] consumed event : ONE
[PRODUCER] published event : ONE

 

Conclusion

Congratulations Readers!  In this article you have learnt the synchronized collections in java, Vector class, HashTable class, SynchronousQueue and the examples.

For more interview questions and answers for Java : Go here .

For complete understanding of ArrayList in Java : Go here .

For complete understanding of TreeMap in Java : Go here .

For complete understanding of BigDecimal in Java : Go here .

For other Java concepts : Go here .

Thanks a lot for reading this article.

Please share your queries / suggestions / questions in below comment box. You can also directly connect with me through social media accounts.

Leave a Reply

Your email address will not be published. Required fields are marked *