First of all I checked previous questions about this topic, however none fits my specific problem.
I got the following Code that illustrates sensors with a timestamp and data stored in a double array, additionally an instance of my implemented FairRWLock.
class LockedSensors implements Sensors {
long time = 0;
double data[];
FairRWLock lock = new FairRWLock();
LockedSensors() {
time = 0;
}
// store data and timestamp
// if and only if data stored previously is older (lower timestamp)
public void update(long timestamp, double[] data) {
lock.writeAcquire();
if (timestamp > time) {
if (this.data == null)
this.data = new double[data.length];
time = timestamp;
for (int i = 0; i < data.length; ++i)
this.data[i] = data[i];
}
lock.writeRelease();
}
// pre: val != null
// pre: val.length matches length of data written via update
// if no data has been written previously, return 0
// otherwise return current timestamp and fill current data to array passed
// as val
public long get(double val[]) {
try{
lock.readAcquire();
if (time == 0) return 0;
for (int i = 0; i < data.length; ++i)
val[i] = data[i];
return time;
} finally{lock.readRelease();}
}
}
It supports an update, which depends on the time when new data was received, and get, which extracts the data stored in the specific sensor.
This is my implementation of the FairRWLock:
class FairRWLock{
private int readers = 0, writers = 0, readersWaiting = 0, writersWaiting = 0, writersWait = 0;
private static final int ReaderPriority = 30;
private Lock lock = new ReentrantLock();
private Condition readerPass = lock.newCondition();
private Condition writerPass = lock.newCondition();
/*
* readers denotes the number of current readers, writers equivalent, readersWaiting denotes the number of readers
* awaiting their signal, writersWaiting equivalent. writersWait denotes the number of readers the writers have to
* let pass before they can proceed, this amount is controlled by the ReaderPriority (reset occurs when writer releases)
*/
/*
* increment the number of waiting readers, check if there are any currently working writers OR writers are waiting
* whilst they don't have to let any readers pass. When signaled, decrement readersWaiting, decrement the number of
* readers the writers have to let pass and increment the number of current readers.
*/
public void readAcquire(){
lock.lock();
readersWaiting++;
while(writers > 0 || (writersWaiting > 0 && writersWait <= 0)){
try {
readerPass.await();
} catch (InterruptedException e) {}
}
readersWaiting--;
writersWait--;
readers++;
lock.unlock();
}
/*
* simply decrement number of readers and signal the threads that have to be signaled
*/
public void readRelease(){
lock.lock();
readers--;
signaling();
lock.unlock();
}
/*
* increment number of waiting writers, check if there are currently working writers OR readers OR readers currently
* have priority over the writers. When signaled decrement writersWaiting, increment number of writers
*/
public void writeAcquire(){
lock.lock();
writersWaiting++;
while(writers > 0 || readers > 0 || (readersWaiting > 0 && writersWait > 0)){
try{
writerPass.await();
} catch(InterruptedException e) {}
}
writersWaiting--;
writers++;
lock.unlock();
}
/*
* simply decrement number of current writers, reset the number of readers the writers have to let pass before
* another writer may pass. signal the ones that should be
*/
public void writeRelease(){
lock.lock();
writers--;
writersWait = ReaderPriority;
signaling();
lock.unlock();
}
/*
* check first if readers currently got priority over the writers. if so (readersWaiting??) ? signal them : signalAll,
* if not (writersWaiting??) ? signal them : signalAll
*/
private void signaling(){
if(writersWait > 0){
if(readersWaiting > 0) readerPass.signalAll();
else writerPass.signal();
} else{
if(writersWaiting > 0) writerPass.signal();
else readerPass.signalAll();
}
}
}
I'm not very familiar with the locking by conditions and it seems my code suffers either from starvation or even deadlock. However I can't find the issue (which most probably is somewhere in the FairRWLock implementation).