/**
*
*/
package com.trendrr.oss.concurrent;
import java.util.Date;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
*
* this lock will allow one thread access every x milliseconds.
*
* all threads will block while the single thread has the lock.
* it is useful for reinitialization code.
*
* @author dustin
*
*/
public class PeriodicLock {
protected static Log log = LogFactory.getLog(PeriodicLock.class);
ExpirationLock timedlock = new ExpirationLock();
TrendrrLock lock = new TrendrrLock();
long period;
public PeriodicLock(long delay, long period) {
Date until = new Date( new Date().getTime() + delay);
timedlock.lockUntil(until);
this.period = period;
}
/**
* will return true if the lock is obtained. false otherwise.
*
* will block if another thread currently holds the lock, then will return
* false when the other thread releases the lock.
*
* @return
*/
public boolean lockOrWait() {
if (timedlock.isLocked() && !lock.isLocked()) {
// log.info("timedlock is not locked: returning");
return false;
}
// log.info("lock or wait");
lock.lockOrWait();
// log.info("got periodic lock");
if (timedlock.isLocked()) {
lock.unlock();
return false;
}
timedlock.lockUntil(new Date( new Date().getTime() + this.period));
return true;
}
/**
* same as above, only will return false if the timedlock is locked or if another thread is
* accessing the restricted code.
*
* @return
*/
public boolean lockOrSkip() {
if (timedlock.isLocked())
return false;
if (lock.lockOrSkip() ) {
if (timedlock.isLocked()) {
lock.unlock();
return false;
}
timedlock.lockUntil(new Date( new Date().getTime() + this.period));
return true;
}
return false;
}
public void unlock() {
lock.unlock();
}
/**
* forces the next time the lock will unlock.
* @param date
*/
public void lockUntil(Date date) {
lock.lockOrWait();
try {
this.timedlock.lockUntil(date);
} finally {
lock.unlock();
}
}
public Date getNextUnlock() {
return timedlock.getLockUntil();
}
}