All Downloads are FREE. Search and download functionalities are using the official Maven repository.

Alachisoft.NCache.Common.Threading.Monitor Maven / Gradle / Ivy

There is a newer version: 5.3.3
Show newest version
/*
 * 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;
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy