package linkedlists.lockbased; import java.util.concurrent.locks.ReentrantReadWriteLock; import contention.abstractions.AbstractCompositionalIntSet; /** * A linked list implementation of an integer set that * uses a reader lock for contains and a write lock for updates. * * @author Vincent Gramoli */ public class RWLockCoarseGrainedListIntSet extends AbstractCompositionalIntSet { final private Node head; final private Node tail; private ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); public RWLockCoarseGrainedListIntSet(){ tail = new Node(Integer.MAX_VALUE); head = new Node(Integer.MIN_VALUE, tail); } public boolean addInt(int item){ lock.writeLock().lock(); try { Node pred = head; Node curr = head.next; while (curr.key < item) { pred = curr; curr = pred.next; } if (curr.key == item){ return false; } else { pred.next = new Node(item, curr); return true; } } finally{ lock.writeLock().unlock(); } } @Override public boolean removeInt(int item) { lock.writeLock().lock(); try { Node pred = head; Node curr = head.next; while (curr.key < item) { pred = curr; curr = pred.next;} if (curr.key == item) { pred.next = curr.next; return true; } else { return false; } } finally { lock.writeLock().unlock(); } } public boolean containsInt(int item){ lock.readLock().lock(); try { Node pred=head; Node curr=head.next; while (curr.key < item) { pred = curr; curr = pred.next; } return (curr.key == item); } finally { lock.readLock().unlock(); } } @Override public int size() { int size = 0; Node curr = head.next; Node pred; lock.readLock().lock(); try { while (curr.next != null) { pred = curr; curr = pred.next; size++; } } finally { lock.readLock().unlock(); } return size; } @Override public void clear() { head.next = tail; } /** * The node of an integer list */ private class Node { final public int key; public Node next; Node(int item) { key = item; next = null; } Node(int item, Node n) { key = item; next = n; } } }