/** * */ package com.trendrr.oss.concurrent; import java.util.Date; import java.util.concurrent.atomic.AtomicLong; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * @author dustin * */ public class ExpirationLock { protected static Log log = LogFactory.getLog(ExpirationLock.class); AtomicLong until = new AtomicLong(0); TrendrrLock lock = new TrendrrLock(); public static void main(String ...args) throws Exception{ // final ExpirationLock lock = new ExpirationLock(); // // for (int i=0; i < 2; i++) { // new Thread((new Runnable(){ // @Override // public void run() { // log.info("LOCKING "); // while(true) { // if (lock.lockOrSkip(TimeHelper.addMinutes(new Date(), 1))) { // log.info("GOT THE LOCK!"); // Sleep.seconds(30); // log.info("DONE SLEEPING"); // // } // Sleep.seconds(5); // log.info("Didnt get the lock"); // } // // } // })).start(); // } } /** * returns true if the lock was set. false if the lock was already set by someone else. * no need to unlock as the lock expires * * non-reentrant. * * * @param until * @return */ public boolean lockOrSkip(Date until) { if (!this.isLocked()) { log.info("Got timed lock try synch lock"); if (lock.lockOrSkip()) { try { log.info("Got synch lock, trying timed again"); if (this.isLocked()) { log.info("unable to get second lock"); //we double check as waiting threads might have just obtained the lock. return false; } this.lockUntil(until); log.info("Got lock, locked until: " + this.getLockUntil()); return true; } finally { lock.unlock(); } } } return false; } /** * Sets the time that the lock will next be available. * @param date */ public void lockUntil(Date date) { this.until.set(date.getTime()); } public Date getLockUntil() { return new Date(this.until.get()); } public boolean isLocked() { return new Date().before(this.getLockUntil()); } }