net.wimpi.telnetd.util.ReentrantLock.java Source code

Java tutorial

Introduction

Here is the source code for net.wimpi.telnetd.util.ReentrantLock.java

Source

//@license@
package net.wimpi.telnetd.util;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * <p/>
 *
 * @author Doug Lea
 * @version @version@ (@date@)
 */
public class ReentrantLock {

    private static final Log log = LogFactory.getLog(ReentrantLock.class);
    protected Thread m_Owner = null;
    protected long m_Holds = 0;

    public void acquire() throws InterruptedException {
        //log.debug("acquire()::" + Thread.currentThread().toString());
        if (Thread.interrupted())
            throw new InterruptedException();
        Thread caller = Thread.currentThread();
        synchronized (this) {
            if (caller == m_Owner)
                ++m_Holds;
            else {
                try {
                    while (m_Owner != null)
                        wait();
                    m_Owner = caller;
                    m_Holds = 1;
                } catch (InterruptedException ex) {
                    notify();
                    throw ex;
                }
            }
        }
    }//acquire

    public boolean attempt(long msecs) throws InterruptedException {
        //log.debug("attempt()::" + Thread.currentThread().toString());
        if (Thread.interrupted())
            throw new InterruptedException();
        Thread caller = Thread.currentThread();
        synchronized (this) {
            if (caller == m_Owner) {
                ++m_Holds;
                return true;
            } else if (m_Owner == null) {
                m_Owner = caller;
                m_Holds = 1;
                return true;
            } else if (msecs <= 0)
                return false;
            else {
                long waitTime = msecs;
                long start = System.currentTimeMillis();
                try {
                    for (;;) {
                        wait(waitTime);
                        if (caller == m_Owner) {
                            ++m_Holds;
                            return true;
                        } else if (m_Owner == null) {
                            m_Owner = caller;
                            m_Holds = 1;
                            return true;
                        } else {
                            waitTime = msecs - (System.currentTimeMillis() - start);
                            if (waitTime <= 0)
                                return false;
                        }
                    }
                } catch (InterruptedException ex) {
                    notify();
                    throw ex;
                }
            }
        }
    }//attempt

    /**
     * Release the lock.
     *
     * @throws Error thrown if not current owner of lock
     */
    public synchronized void release() {
        //log.debug("release()::" + Thread.currentThread().toString());
        if (Thread.currentThread() != m_Owner)
            throw new Error("Illegal Lock usage");

        if (--m_Holds == 0) {
            m_Owner = null;
            notify();
        }
    }//release

    /**
     * Release the lock N times. <code>release(n)</code> is
     * equivalent in effect to:
     * <pre>
     *   for (int i = 0; i < n; ++i) release();
     * </pre>
     * <p/>
     *
     * @throws Error thrown if not current owner of lock
     *               or has fewer than N holds on the lock
     */
    public synchronized void release(long n) {
        if (Thread.currentThread() != m_Owner || n > m_Holds)
            throw new Error("Illegal Lock usage");

        m_Holds -= n;
        if (m_Holds == 0) {
            m_Owner = null;
            notify();
        }
    }//release

    /**
     * Return the number of unreleased acquires performed
     * by the current thread.
     * Returns zero if current thread does not hold lock.
     */
    public synchronized long holds() {
        if (Thread.currentThread() != m_Owner)
            return 0;
        return m_Holds;
    }//holds

}//class ReentrantLock