The following solution has a race condition on deletion. It also behaves slightly differently than standard JDK Set implementations.
However, it uses standard JDK objects and is a simple implementation. Only you can decide if this condition of the race is acceptable, or if you want to invest time to find / implement a solution without races.
public class FifoSet<T> { private ConcurrentHashMap<T,T> _map; private ConcurrentLinkedQueue<T> _queue; public void add(T obj) { if (_map.put(obj,obj) != null) return; _queue.add(obj); } public T removeFirst() { T obj = _queue.remove(); _map.remove(obj); return obj; } }
One more explanation: ConcurrentHashMap exists only as protection on ConcurrentLinkedList ; its put() method is essentially a comparison and a replacement. This way, you will make sure that you do not have anything on the card before adding to the queue, and you do not delete the card until you remove it from the queue.
The race condition when deleting is the time interval between removing an item from the queue and deleting it from the map. During this period of time, the addition will not be performed because it still considers that the item is in the queue.
This is a relatively minor race condition. One that is far less important than the length of time between removing an item from the queue and actually doing something with that item.
source share