A solution to the readers-writers problem using semaphores in Java. First, a Reader. package semaphore; import java.util.Random; import java.util.concurrent.Semaphore; /** * A reader. * * @author Franck van Breugel */ public class Reader extends Thread { private static int readers = 0; private static final Semaphore mutex = new Semaphore(1); /** * Initializes this reader. */ public Reader() { super(); } /** * Reads. */ public void run() { try { Reader.mutex.acquire(); Reader.readers++; if (Reader.readers == 1) { Writer.writer.acquire(); } Reader.mutex.release(); // read Reader.mutex.acquire(); Reader.readers--; if (Reader.readers == 0) { Writer.writer.release(); } Reader.mutex.release(); } catch (InterruptedException e) {} } } Then, a Writer. package semaphore; import java.util.Random; import java.util.concurrent.Semaphore; /** * A writer. * * @author Franck van Breugel */ public class Writer extends Thread { public static final Semaphore writer = new Semaphore(1, true); /** * Initializes this writer. */ public Writer() { super(); } /** * Writes. */ public void run() { try { Writer.writer.acquire(); // write Writer.writer.release(); } catch (InterruptedException e) {} } } And finally an app. package semaphore; /** * This app creates a number of readers and writers. * * @author Franck van Breugel */ public class ReadersWriters { /** * @param args[0] numbers of readers. * @param args[1] number of writers. */ public static void main(String[] args) { try { int readers = Integer.parseInt(args[0]); int writers = Integer.parseInt(args[1]); for (int i = 0; i < writers; i++) { new Writer().start(); } for (int i = 0; i < readers; i++) { new Reader().start(); } } catch (Exception e) { System.out.println("Usage: java ReadersWriters < number of readers> "); } } } Below, we present another solution to the readers-writers problem. /** * This class represents a database. There are many * competing threads wishing to read and write. It is * acceptable to have multiple processes reading at the * same time, but if one thread is writing then no other * process may either read or write. */ public class Database { private int readers; // number of active readers /** * Initializes this database. */ public Database() { this.readers = 0; } /** * Read from this database. */ public void read(int number) { synchronized(this) { this.readers++; } // read synchronized(this) { this.readers--; if (this.readers == 0) { this.notifyAll(); } } } /** * Writes to this database. */ public synchronized void write(int number) { while (this.readers != 0) { try { this.wait(); } catch (InterruptedException e) {} } // write this.notifyAll(); } }