/**
*
*/
package com.trendrr.oss.concurrent;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.ReentrantLock;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* @author dustin
*
*/
public class TrendrrLock {
protected static Log log = LogFactory.getLog(TrendrrLock.class);
protected AtomicBoolean once = new AtomicBoolean(false);
ReentrantLock lock = new ReentrantLock();
public static void main(String ...args) throws Exception{
final TrendrrLock lock = new TrendrrLock();
for (int i=0; i < 3; i++) {
new Thread((new Runnable(){
@Override
public void run() {
log.info("LOCKING ");
if (lock.lockOnce()) {
log.info("GOT THE LOCK MOFO!");
Sleep.seconds(30);
log.info("DONE SLEEPING");
lock.unlock();
}
log.info("UNLOCKING");
}
})).start();
}
}
/**
* returns true if lock was obtained, false otherwise.
* @return
*/
public boolean lockOrSkip() {
try {
return lock.tryLock(0, TimeUnit.SECONDS);
} catch (Exception x) {
log.error("Caught", x); //this should never happen
}
return false;
}
public boolean isLocked() {
return lock.isLocked();
}
public void lockOrWait() {
lock.lock();
}
public void unlock() {
once.set(true);
lock.unlock();
}
/**
* used for lazy initializations. will block if and only if initialization is currently happening.
*
* returns true if successfully locked, false otherwise
*
* remember to unlock!
*
* reset by calling resetLockOnce();
*
*/
public boolean lockOnce() {
if (!once.get()) {
//now lock..
lock.lock();
//check if a previous thread already initialized
if (once.get()) {
lock.unlock();
}
}
return !once.get();
}
/**
* use this to reset the value for lockOnce..
* @param val
*/
public void resetLockOnce() {
once.set(false);
}
/**
* set to true if you say the the lock has already been gotten
* @param val
*/
public void setLockOnce(boolean val) {
once.set(val);
}
}