// Buffer.java import java.util.*; import java.util.concurrent.Semaphore; /* Holds the transactions for the worker threads. */ public class Buffer { public static final int SIZE = 64; private ArrayList<Transaction> transactions; private Semaphore canAdd; private Semaphore canRemove; private Object alterLock; /** * Constructor */ public Buffer() { transactions = new ArrayList<Transaction>(); canAdd = new Semaphore(SIZE); canRemove = new Semaphore(0); alterLock = new Object(); } /** * Adds a transaction to the buffer * @param t the transaction to add */ public void add(Transaction t) { // check if we can add (buffer is not full) try { canAdd.acquire(); } catch (InterruptedException ignored) {} // synchronize so as not to try to add 2+ objects at the same time synchronized(alterLock) { transactions.add(t); } // signal to remove that there's at least one element in the buffer canRemove.release(); } /** * Gets the first transaction in the buffer * @return the first transaction */ public Transaction remove() { // check if there's an item to remove try { canRemove.acquire(); } catch (InterruptedException ignored) {} Transaction t; // synchronize the change of the ArrayList synchronized(alterLock) { t = transactions.remove(0); } // signal that we have removed an element canAdd.release(); return t; } }