Alachisoft.NCache.Common.Threading.Monitor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of nc-common Show documentation
Show all versions of nc-common Show documentation
Internal package of Alachisoft.
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package Alachisoft.NCache.Common.Threading;
import java.util.LinkedList;
import java.util.List;
/**
* @author taimoor_haider
*/
public class Monitor {
static final Object s_mutex = new Object();
static List s_watingObjects = new LinkedList();
public static boolean wait(Object waitObject) throws InterruptedException {
return wait(waitObject, Long.MAX_VALUE);
}
public static boolean wait(Object waitObject, long timeout) throws InterruptedException {
boolean lockReacquired = true;
if (timeout <= 0) timeout = Long.MAX_VALUE;
WaitableObject waitingObject = new WaitableObject(waitObject);
try {
synchronized (s_mutex) {
s_watingObjects.add(waitingObject);
}
long timeElapsed = 0;
while (!waitingObject.isPulsed()) {
timeout = timeout - timeElapsed;
if (timeout <= 0) {
//return false;
lockReacquired = false;
break;
}
timeElapsed = waitingObject.waitObject(timeout);
if (timeElapsed <= 0 && !waitingObject.isPulsed()) {
//timeout has elapsed
lockReacquired = false;
break;
}
}
} finally {
synchronized (s_mutex) {
for (int i = 0; i < s_watingObjects.size(); i++) {
WaitableObject currentWaitingObject = s_watingObjects.get(i);
if (currentWaitingObject.getUniqueId() == waitingObject.getUniqueId()) {
s_watingObjects.remove(i);
break;
}
}
}
}
return lockReacquired;
}
public static void pulse(Object waitObject) {
WaitableObject waitingObject = null;
synchronized (s_mutex) {
for (int i = 0; i < s_watingObjects.size(); i++) {
waitingObject = s_watingObjects.get(i);
if (waitingObject != null && waitingObject.equals(waitObject)) {
waitingObject.pulseObject();
waitingObject.pulsingThread = Thread.currentThread().getName();
}
}
}
}
public static void pulseAll() {
WaitableObject waitingObject = null;
synchronized (s_mutex) {
for (int i = 0; i < s_watingObjects.size(); i++) {
waitingObject = s_watingObjects.get(i);
if (waitingObject != null) {
waitingObject.pulseObject();
waitingObject.pulsingThread = Thread.currentThread().getName();
}
}
}
}
static class WaitableObject {
private static int s_unique_id_generator;
private static Object s_unique_id_mutex = new Object();
private Object objectToWaitFor;
private boolean pulsed;
private int pulseCount;
private int uniqueId;
private String pulsingThread;
private long waitingThreadId;
private long waitTime;
private short wakeupCount;
public WaitableObject(Object objectToWaitFor) {
this.objectToWaitFor = objectToWaitFor;
synchronized (s_unique_id_mutex) {
this.uniqueId = s_unique_id_generator++;
}
}
@Override
public boolean equals(Object obj) {
if (obj != null && obj instanceof WaitableObject) {
if (this.objectToWaitFor == ((WaitableObject) obj).objectToWaitFor) {
return true;
}
} else if (obj != null && this.objectToWaitFor == obj) {
return true;
}
return false;
}
/*
* Returns timeelapsed
*/
public long waitObject(long timeout) throws InterruptedException {
waitingThreadId = Thread.currentThread().getId();
waitTime = timeout;
synchronized (objectToWaitFor) {
if (pulsed) {
return -1;
}
long start = System.currentTimeMillis();
objectToWaitFor.wait(timeout);
wakeupCount++;
//return ThreadUtil.wait(objectToWaitFor, timeout);
long end = System.currentTimeMillis();
if (start > end) {
return -1;
}
return end - start;
}
}
public void pulseObject() {
synchronized (objectToWaitFor) {
pulsed = true;
pulseCount++;
objectToWaitFor.notifyAll();
objectToWaitFor.notify();
}
}
public boolean isPulsed() {
synchronized (objectToWaitFor) {
return pulsed;
}
}
public int getUniqueId() {
return uniqueId;
}
}
}