[concurrency-interest] Critique my class ?

Chris Burnley chris.burnley at gmail.com
Thu Sep 22 06:09:26 EDT 2005


I have a use case where I've got several client threads that write to a
FileChannel but I must guarantee that the file gets synced for each client.
A file sync could take up to 40ms depending on the size of the file. To get
around this I want to buffer up the clients so I only have to do the sync
once every, say 50ms, thus drastically improving the throughput at the cost
of a little latency.

Question : is there something already available that would help me do this
sort of thing ? I thought maybe a cyclicbarrier but somehow it didn't fit (
I'm not concerned with the number of clients waiting but rather the time
elapsed since last sync)

Otherwise, can anybody see anything wrong with the following implementation
? (I've called it Switch for want of a better term).


class Switch {

private Lock lock = new ReentrantLock();

private Condition condition = lock.newCondition();

private boolean waiters;
private Exception failure;

/**
* Lock, but only if there are waiters.
* @return if the lock was acquired.
*/
public boolean lockIfWaiters() {
lock.lock();
failure = null;
if (!waiters) {
lock.unlock();
return false;
}
return true;
}

/**
* Unlock the switch and notify all those that have been waiting.
*/
public void unlockAndSignalAll() {
waiters = false;
condition.signalAll();
lock.unlock();
}

/**
* Indicate to waiters that the operation has failed.
*
*/
public void signalFailure(Exception cause){
this.failure = cause;
unlockAndSignalAll();
}

/**
* Used by waiters on the switch.
* @throws InterruptedException
*/
public void await() throws InterruptedException, WaitFailureException{
lock.lock();
try {
waiters = true;
condition.await();
if(failure != null)
throw new WaitFailureException(failure);
} finally {
lock.unlock();
}
}
}

The clients call this method after they've written to the channel:


protected void force() throws SyncFailedException {
try {
swtch.await();
} catch (InterruptedException e) {
throw new SyncFailedException(e.toString());
} catch (WaitFailureException e) {
throw new SyncFailedException(e.toString());
}
}



and I have a scheduled task that does the actual file sync:

class FileSyncer implements Runnable {

public void run() {
while (swtch.lockIfWaiters()) {
try {
fileChannel.force(false);
swtch.unlockAndSignalAll();
} catch (Exception e){
// error logging omitted
swtch.signalFalure(e);
}
}
}
}

regards,

Chris Burnley
-------------- next part --------------
An HTML attachment was scrubbed...
URL: /pipermail/attachments/20050922/5c2d2773/attachment.htm


More information about the Concurrency-interest mailing list