I am trying to create a basic Semaphore implementation using Queue. The idea is, there is a database, and there are 10 writers. Writers can only write to the database in mutual exclusion. I am using Queue because I want to implement First In First Out and Last In First Out.
Using Semaphore, I can't notify a specific thread to wake up. So my idea is what I am doing is for every Writer, I create an object and tell the Writer to wait on that object. Puts that object in a queue. Then remove the object from the queue and notify the Thread that is waiting on that object. In this way, I think I can make a FIFO or LIFO implementation.
I need help on the actual code implementation: 1. I run the code below, it gave me a lot of IllegalMonitorStateException. 2. FIFO and LIFO code (my FIFO code seems incorrect, while for LIFO code, I'm thinking to use Stack instead of Queue).
public class Test {
public static void main(String [] args) {
Database db = new Database();
for (int i = 0; i < 10; i++)
(new Thread(new Writer(db))).start();
}
}
public class Writer implements Runnable {
private Database database;
public Writer(Database database) {
this.database = database;
}
public void run() {
this.database.acquireWriteLock();
this.database.write();
this.database.releaseWriteLock();
}
}
public class Database {
private Semaphore lockQueue;
public Database() {
this.lockQueue = new Semaphore();
}
public void write() {
try {
Thread.sleep(1000);
} catch (InterruptedException ie) {}
}
public void acquireWriteLock() {
lockQueue.acquire();
}
public void releaseWriteLock() {
lockQueue.release();
}
}
import java.util.Queue;
import java.util.LinkedList;
public class Semaphore {
private Queue<Object> queue;
public Semaphore() {
this.queue = new LinkedList<Object>();
}
public synchronized void acquire() {
Object object = new Object();
try {
if (this.queue.size() > 0) {
object.wait();
this.queue.add(object);
}
} catch (InterruptedException ie) {}
this.queue.add(object);
}
public synchronized void release() {
Object object = this.queue.remove();
object.notify();
}
}