readers-writers
Differences
This shows you the differences between two versions of the page.
| readers-writers [2007/10/05 12:24] – external edit 127.0.0.1 | readers-writers [2009/04/26 19:42] (current) – franck | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ====== | + | A solution to the readers-writers problem |
| - | + | First, a Reader. | |
| - | We start with the database. | + | |
| <code java> | <code java> | ||
| + | package semaphore; | ||
| + | |||
| + | import java.util.Random; | ||
| + | import java.util.concurrent.Semaphore; | ||
| + | |||
| /** | /** | ||
| - | This class represents a database. | + | * A reader. |
| - | competing threads wishing to read and write. It is | + | * |
| - | | + | * @author Franck van Breugel |
| - | same time, but if one thread is writing then no other | + | |
| - | process may either read or write. | + | |
| */ | */ | ||
| - | public class Database | + | public class Reader extends Thread |
| { | { | ||
| - | private int readers; | + | private |
| + | private static final Semaphore mutex = new Semaphore(1); | ||
| + | | ||
| /** | /** | ||
| - | | + | |
| - | */ | + | |
| - | public | + | public |
| { | { | ||
| - | | + | |
| } | } | ||
| + | | ||
| /** | /** | ||
| - | Read from this database. | + | * Reads. |
| - | + | | |
| - | @param number Number of the reader. | + | public void run() |
| - | */ | + | |
| - | public void read(int number) | + | |
| { | { | ||
| - | synchronized(this) | ||
| - | { | ||
| - | this.readers++; | ||
| - | System.out.println(" | ||
| - | } | ||
| - | |||
| - | final int DELAY = 5000; | ||
| try | try | ||
| { | { | ||
| - | | + | |
| - | } | + | |
| - | catch (InterruptedException e) {} | + | if (Reader.readers == 1) |
| - | + | ||
| - | synchronized(this) | + | |
| - | { | + | |
| - | | + | |
| - | this.readers--; | + | |
| - | if (this.readers == 0) | + | |
| { | { | ||
| - | | + | |
| } | } | ||
| - | } | + | Reader.mutex.release(); |
| - | } | + | // read |
| - | + | | |
| - | /** | + | |
| - | Writes to this database. | + | |
| - | + | ||
| - | @param number Number of the writer. | + | |
| - | */ | + | |
| - | | + | |
| - | { | + | |
| - | | + | |
| - | { | + | |
| - | try | + | |
| { | { | ||
| - | | + | |
| } | } | ||
| - | | + | |
| - | } | + | |
| - | System.out.println(" | + | |
| - | + | ||
| - | final int DELAY = 5000; | + | |
| - | try | + | |
| - | { | + | |
| - | Thread.sleep((int) (Math.random() * DELAY)); | + | |
| } | } | ||
| catch (InterruptedException e) {} | catch (InterruptedException e) {} | ||
| - | + | | |
| - | System.out.println(" | + | |
| - | this.notifyAll(); | + | |
| - | } | + | |
| } | } | ||
| </ | </ | ||
| - | + | Then, a Writer. | |
| - | Next, we present the reader. | + | |
| <code java> | <code java> | ||
| + | package semaphore; | ||
| + | |||
| + | import java.util.Random; | ||
| + | import java.util.concurrent.Semaphore; | ||
| + | |||
| /** | /** | ||
| - | This class represents a reader. | + | * A writer. |
| - | */ | + | * |
| - | public class Reader | + | * @author Franck van Breugel |
| + | */ | ||
| + | public class Writer | ||
| { | { | ||
| - | | + | |
| - | + | ||
| - | private int number; | + | |
| - | private Database database; | + | |
| /** | /** | ||
| - | Creates a Reader for the specified database. | + | * Initializes this writer. |
| - | + | | |
| - | @param database database from which to be read. | + | public |
| - | */ | + | |
| - | public | + | |
| { | { | ||
| - | | + | |
| - | this.number = Reader.readers++; | + | |
| } | } | ||
| + | |||
| /** | /** | ||
| - | Reads. | + | * Writes. |
| - | */ | + | |
| public void run() | public void run() | ||
| { | { | ||
| - | | + | |
| { | { | ||
| - | | + | |
| - | try | + | |
| - | { | + | |
| - | Thread.sleep((int) (Math.random() * DELAY)); | + | |
| - | | + | |
| - | | + | |
| - | this.database.read(this.number); | + | |
| } | } | ||
| + | catch (InterruptedException e) {} | ||
| } | } | ||
| } | } | ||
| </ | </ | ||
| - | + | And finally an app. | |
| - | Next, we present the writer. | + | |
| <code java> | <code java> | ||
| + | package semaphore; | ||
| + | |||
| /** | /** | ||
| - | | + | |
| - | */ | + | * |
| - | public class Writer extends Thread | + | * @author Franck van Breugel |
| + | */ | ||
| + | public class ReadersWriters | ||
| { | { | ||
| - | private static int writers = 0; // number of writers | ||
| - | |||
| - | private int number; | ||
| - | private Database database; | ||
| - | |||
| /** | /** | ||
| - | Creates a Writer for the specified database. | + | * @param args[0] numbers of readers. |
| - | + | * @param | |
| - | | + | |
| - | */ | + | public |
| - | public | + | |
| { | { | ||
| - | | + | |
| - | this.number = Writer.writers++; | + | |
| - | } | + | |
| - | + | ||
| - | /** | + | |
| - | Writes. | + | |
| - | */ | + | |
| - | public void run() | + | |
| - | { | + | |
| - | while (true) | + | |
| { | { | ||
| - | | + | int readers |
| - | | + | |
| + | for (int i = 0; i < writers; i++) | ||
| { | { | ||
| - | | + | |
| + | } | ||
| + | for (int i = 0; i < readers; i++) | ||
| + | { | ||
| + | new Reader().start(); | ||
| } | } | ||
| - | | + | } |
| - | | + | |
| + | | ||
| + | | ||
| } | } | ||
| } | } | ||
| Line 170: | Line 129: | ||
| </ | </ | ||
| - | Finally, we present the simulator. | + | Below, we present |
| <code java> | <code java> | ||
| /** | /** | ||
| - | | + | |
| - | writers | + | * competing threads wishing to read and write. |
| - | */ | + | * acceptable to have multiple processes reading at the |
| - | public class Simulator | + | * 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 | ||
| + | |||
| /** | /** | ||
| - | Creates the specified number of readers and writers and starts them. | + | * Initializes this database. |
| - | + | | |
| - | @param args[0] The number of readers. | + | public |
| - | | + | |
| - | | + | |
| - | public | + | |
| { | { | ||
| - | | + | |
| + | } | ||
| + | |||
| + | /** | ||
| + | * Read from this database. | ||
| + | */ | ||
| + | public void read(int number) | ||
| + | { | ||
| + | synchronized(this) | ||
| { | { | ||
| - | | + | |
| } | } | ||
| - | | + | |
| + | synchronized(this) | ||
| { | { | ||
| - | | + | |
| - | | + | |
| - | Database database | + | |
| - | for (int i = 0; i < READERS; i++) | + | |
| { | { | ||
| - | | + | |
| } | } | ||
| - | for (int i = 0; i < WRITERS; i++) | + | } |
| + | } | ||
| + | |||
| + | /** | ||
| + | * Writes to this database. | ||
| + | */ | ||
| + | public synchronized void write(int number) | ||
| + | { | ||
| + | while (this.readers != 0) | ||
| + | { | ||
| + | try | ||
| { | { | ||
| - | | + | |
| } | } | ||
| + | catch (InterruptedException e) {} | ||
| } | } | ||
| + | // write | ||
| + | this.notifyAll(); | ||
| } | } | ||
| } | } | ||
| </ | </ | ||
readers-writers.1191587067.txt.gz · Last modified: (external edit)
