package queues.lockfree; import java.util.Collection; import java.util.Random; import java.util.concurrent.ConcurrentLinkedQueue; import contention.abstractions.CompositionalIntSet; import contention.benchmark.Parameters; /** * Lock-free Queue (linked list) implementation of the integer set * as part of the JDK. * It builds upon the Michael and Scott algorithm, PODC 1996. * * @author Vincent Gramoli * */ public class LockFreeQueueIntSet implements CompositionalIntSet { private static final long serialVersionUID = 0001; private final ConcurrentLinkedQueue<Integer> queue = new ConcurrentLinkedQueue<Integer>(); /** The thread-private PRNG */ final private static ThreadLocal<Random> s_random = new ThreadLocal<Random>() { @Override protected synchronized Random initialValue() { return new Random(); } }; public void fill(final int range, final long size) { while (this.size() < size) { this.addInt(s_random.get().nextInt(range)); } } public void push(int value) { queue.add(value); } public boolean addInt(int value) { return queue.add(value); } public boolean addAll(Collection<Integer> c) { return queue.addAll(c); } public int size() { return queue.size(); } public int pop() { return queue.remove(); } public boolean removeInt(int value) { return queue.remove(value); } public boolean removeAll(Collection<Integer> c) { return queue.removeAll(c); } public boolean containsInt(int x) { return queue.contains(x); } /** * This is called after the JVM warmup phase * to make sure the data structure is well initalized. * No need to do anything for this. * * Note the ugly hack to reset the init size of the queue after warmup * otherwise queue size grows as fast as its add ops execute: they are * always successful, as opposed to its remove. */ public void clear() { queue.clear(); fill(Parameters.range, Parameters.size); return; } @Override public Object getInt(int x) { if (containsInt(x)) return x; return null; } @Override public Object putIfAbsent(int x, int y) { System.err.println("Lock-free queue cannot atomically putIfAbsent."); return null; } }