请考虑这种方法 - 它允许无限的读者,并且当作者想要写作时,它会等待当前读者完成写作。
class readWriteSemaphore() {
private Object lock;
List readers;
Thread writer;
readWriteSemaphore() {
readers = new LinkedList(); // Linked list is inefficient for many threads, FYI
writer = null;
}
/**
* Returns true if and only if you have acquired a read
* maybe use while(!rws.acquireRead(Thread.currentThread())) Thread.sleep(50); // or something
*/
boolean acquireRead(Thread t) {
synchronized(lock) {
if(writer == null) {
readers.add(t);
return true;
}
return false; // yes this could go outside the synch block... oh well
}
}
void releaseRead(Thread t) {
synchronized(lock) {
while(readers.remove(t)); // remove this thread completely
}
}
boolean acquireWrite(Thread t) {
synchronized(lock) {
if(writer == null) return false;
writer = t;
}
while(readers.size() > 0) Thread.sleep(50); // give readers time to finish.
//They can't re-enter yet because we set the writer,
// if you attempt to acquire a write, future reads will be false until you're done
return true;
}
void releaseWrite(Thread t) {
synchronized(lock) {
if(t != writer) throw new IllegalArgumentException("Only writer can release itself");
writer = null;
}
}
}