SoFunction
Updated on 2025-03-09

The use of some common concurrent collection classes in Java

What are concurrent collections?

List some common concurrent collection classes

Concurrent collections are special data structures that allow multiple threads to safely access and modify. In the scenario of multi-threaded programming, only using concurrent sets can thread safety be ensured, and race conditions and other concurrency errors caused by multiple threads when performing concurrent operations on the same data structure.

Common concurrent collection classes include:

  • ArrayBlockingQueue: A blocking queue based on array implementation, the capacity must be specified when creating an object.
  • ConcurrentLinkedQueue: A thread-safe, linked node-based, optional capacity-free non-blocking queue.
  • LinkedBlockingQueue: A blocking queue based on a linked list that sorts elements by FIFO (first in first out).
  • PriorityBlockingQueue: An unbounded blocking queue that supports priority heaps.
  • DelayQueue: An unbounded blocking queue that supports delayed acquisition of elements.
  • SynchronousQueue: A blocking queue that does not store elements, each insert operation must wait for a corresponding delete operation, and vice versa.
  • LinkedBlockingDeque: A bidirectional blocking queue composed of linked list structure.
  • CopyOnWriteArrayList: A thread-safe mutable array where all mutable operations (add, set, etc.) are implemented by copying the underlying array.
  • CopyOnWriteArraySet: A thread-safe Set implementation based on CopyOnWriteArrayList.

These concurrent collection classes provide thread-safe collection operations, allowing data to be shared and modified safely in a multi-threaded environment.

Example of usage of concurrent collections

The following is a useConcurrentLinkedDequeSimple example of   which shows how to safely add and delete elements in a multithreaded environment:

import ;

public class ConcurrentCollectionExample {

    public static void main(String[] args) throws InterruptedException {

        // Create a concurrent double-ended queue        ConcurrentLinkedDeque<String> deque = new ConcurrentLinkedDeque<>();

        // Add task class to add data to the queue        class AddTask implements Runnable {
            private ConcurrentLinkedDeque<String> deque;

            public AddTask(ConcurrentLinkedDeque<String> deque) {
                 = deque;
            }

            @Override
            public void run() {
                String name = ().getName();
                for (int i = 0; i < 1000; i++) {
                    (name + ":" + i);
                }
            }
        }

        // Delete the task class to delete data from the queue        class PollTask implements Runnable {
            private ConcurrentLinkedDeque<String> deque;

            public PollTask(ConcurrentLinkedDeque<String> deque) {
                 = deque;
            }

            @Override
            public void run() {
                String name = ().getName();
                while (!()) {
                    (name + " removed: " + ());
                }
            }
        }

        // Create and start the thread to add data        Thread addThread1 = new Thread(new AddTask(deque), "AddThread1");
        Thread addThread2 = new Thread(new AddTask(deque), "AddThread2");
        ();
        ();

        // Wait for the thread to add data to complete        ();
        ();

        // Create and start a thread that deletes data        Thread pollThread = new Thread(new PollTask(deque), "PollThread");
        ();

        // The thread waiting for the data to be deleted to complete        ();

        ("Deque is now empty.");
    }
}

In this example, we create aConcurrentLinkedDeque, it is a thread-safe double-ended queue. We define two task classes,AddTaskandPollTask, used to add data to and delete data from the queue, respectively. Both task classes have been implementedRunnableinterfaces, so they can be executed by threads.

existmainIn the method, we create two threads that add data and one thread that deletes data. These two threads adding data will add data to the queue, while the threads that delete data will delete data from the queue until the queue is empty.

By usingConcurrentLinkedDeque, We can safely perform addition and removal operations in a multi-threaded environment without additional synchronization or locking. This is one of the main advantages of concurrent collections.

This is the end of this article about the use of some common concurrent collection classes in Java. For more related contents of Java concurrent collection classes, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!