This Java Concurrency tutorial helps you understand how the concurrent collection CopyOnWriteArraySet in the java.util.concurrent package works.

Actually, a CopyOnWriteArraySet uses a CopyOnWriteArrayList internally for its operations. So you should read this article about CopyOnWriteArrayList in order to fully understand about CopyOnWriteArraySet.

Here’s a summary of key features of a CopyOnWriteArraySet:

  • It’s a thread-safe, and can be used as a thread-safe alternative to HashSet.
  • It allows sequential write and concurrent reads by multiple threads. Only one thread can execute write operations (add and remove), and multiple threads can execute read operations (iterator) at a time.
  • Its iterator doesn’t throw ConcurrentModificationException and doesn’t support remove method.
CopyOnWriteArraySet is a Set so it doesn’t allow duplicate elements. But unlike HashSet, its iterator returns elements in the order they were added.

Therefore, consider using a CopyOnWriteArraySet if you need a thread-safe collection that is similar to CopyOnWriteArrayList but no duplicate elements are allowed.

Also note that you should use CopyOnWriteArraySet only when the read operations outnumber the write operations and has a small number of elements, because the set creates a new copy of its elements for each write operation, which affects performance if the set has a large number of elements and the write operations are frequent.

Let’s see an example that demonstrates how  CopyOnWriteArraySet works. The following program e creates two threads:

- Thread Writer adds a number to CopyOnWriteArraySet for every 5 seconds.

- Thread Reader iterates the list repeatedly with a small delay (10 milliseconds) for every iteration.

Here’s the full source code of the program:

import java.util.*;
import java.util.concurrent.*;

/**
 * This program demonstrates how a CopyOnWriteArraySet works
 * in multi-threading context.
 *
 * @author www.codejava.net
 */
public class CopyOnWriteArraySetTest {

	public static void main(String[] args) {

		Set<Integer> set = new CopyOnWriteArraySet<>();

		set.add(1);
		set.add(2);
		set.add(3);
		set.add(4);
		set.add(5);

		new WriteThread("Writer", set).start();

		new ReadThread("Reader", set).start();

	}
}


class WriteThread extends Thread {

	private Set<Integer> set;

	public WriteThread(String name, Set<Integer> set) {
		this.set = set;
		super.setName(name);
	}

	public void run() {
		int count = 6;

		while (true) {

			try {

				Thread.sleep(5000);

			} catch (InterruptedException ex) {
				ex.printStackTrace();
			}

			set.add(count++);

			System.out.println(super.getName() + " done");
		}
	}
}


class ReadThread extends Thread {
	private Set<Integer> set;

	public ReadThread(String name, Set<Integer> set) {
		this.set = set;
		super.setName(name);
	}

	public void run() {

		while (true) {

			String output = "\n" + super.getName() + ":";

			Iterator<Integer> iterator = set.iterator();

			while (iterator.hasNext()) {
				Integer next = iterator.next();
				output += " " + next;

				// fake processing time
				try {

					Thread.sleep(10);

				} catch (InterruptedException ex) {
					ex.printStackTrace();
				}
			}

			System.out.println(output);
		}
	}
}
You can see that the read operations outnumber the write ones.



Run this program and observe the result. You will see that the reader thread constantly prints out the elements in the list, whereas the writer thread slowly adds a new number to the list. This program runs forever until you press Ctrl + C to stop it.

Try to change the list implementation from CopyOnWriteArraySet to HashSet like this:

Set<Integer> set = new HashSet<>();
Recompile and run the program again, you will see that the reader thread throws ConcurrentModificationException as soon as the writer thread adds a new element to the list. The reader thread die and only the writer thread alive.

 

Other Java Concurrent Collections:

 

Other Java Concurrency Tutorials:


About the Author:

is certified Java programmer (SCJP and SCWCD). He began programming with Java back in the days of Java 1.4 and has been passionate about it ever since. You can connect with him on Facebook and watch his Java videos on YouTube.



Add comment