/** * A database that can be read by multiple readers * at the same time, but can only be written by a * single writer. * * @author Franck van Breugel */ public class Database { private boolean writing; private int readers; private int writers; // introduced to reason about the code /** * Initializes this database. */ public Database() { this.writing = false; this.readers = 0; this.writers = 0; } /** * Reads this database. */ public void read() { this.beginRead(); // read assert !this.writing; this.endRead(); } /** * Waits if a writer is writing. */ private synchronized void beginRead() { while (this.writing) { try { this.wait(); } catch (InterruptedException e) {} } this.readers++; } /** * Notifies waiting writers. */ private synchronized void endRead() { this.readers--; if (this.readers == 0) { this.notifyAll(); } } /** * Writes to this database. */ public void write() { this.beginWrite(); // write assert this.readers == 0 && this.writer == 1; this.endWrite(); } /** * Waits if readers are reading. */ private synchronized void beginWrite() { while (this.writing || this.readers > 0) { try { this.wait(); } catch (InterruptedException e) {} } this.writing = true; this.writers++; } /** * Notifies waiting readers. */ private synchronized void endWrite() { this.writing = false; this.writers--; this.notifyAll(); } }