简体   繁体   中英

Java Non Reentrant Lock Implementation

I have implemented a Non Reentrant Lock. I want to know if this has any mistakes, race conditions etc. I am aware of the fact that existing libraries have to be used (instead of writing our own), but this is just to see if I am understanding the java concurrency correctly. Any feedback is appreciated.

public class MyLock {
private boolean isLocked = false;
private long owner = -1;
private static String TAG = "MyLock: ";

public synchronized void Lock() throws InterruptedException, IllegalStateException {
    if(!isLocked) {
        isLocked = true;
        owner = Thread.currentThread().getId();

    } else {
        if(owner == Thread.currentThread().getId()) {
            throw new IllegalStateException("Lock already acquired. " +
                                            "This lock is not reentrant");
        } else {
            while(isLocked == true) {
                System.out.println(TAG+"Waiting for Lock, Tid = " +
                        Thread.currentThread().getId());
                wait();
            }   
        }
    }
    System.out.println(TAG+"Lock Acquired: Owner = " + owner);
}

public synchronized void Unlock() throws IllegalStateException {
    if(!isLocked || owner != Thread.currentThread().getId()) {
        throw new IllegalStateException("Only Owner can Unlock the lock");
    } else {
        System.out.println(TAG+"Unlocking: Owner = " + owner);
        owner = -1;
        isLocked = false;
        notify();
    }
}

}

Here is an implementation of a "standard" / "non-reentrant" lock in Java, as a wrapper around Java's built-in ReentrantLock that simply prevents the lock from ever being acquired more than once.

/**
 * A "non-reentrant" lock, implemented as a wrapper around Java's ReentrantLock.
 *
 */
class StandardLock implements java.util.concurrent.locks.Lock {

    public static class LockAlreadyHeldException extends RuntimeException {}

    private final java.util.concurrent.locks.ReentrantLock mainLock;

    private void checkNotAlreadyHeld() {
        if (mainLock.getHoldCount()!=0) {
            throw new LockAlreadyHeldException();
        }
    }

    public StandardLock() {
        mainLock=new java.util.concurrent.locks.ReentrantLock();
    }

    public StandardLock(boolean fair) {
        mainLock=new java.util.concurrent.locks.ReentrantLock(fair);
    }

    @Override
    public void lock() {
        checkNotAlreadyHeld();
        mainLock.lock();
    }

    @Override
    public void lockInterruptibly() throws InterruptedException {
        checkNotAlreadyHeld();
        mainLock.lockInterruptibly();
    }

    @Override
    public boolean tryLock() {
        checkNotAlreadyHeld();
        return mainLock.tryLock();
    }

    @Override
    public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
        checkNotAlreadyHeld();
        return mainLock.tryLock(time, unit);
    }

    @Override
    public void unlock() {
        mainLock.unlock();
    }

    @Override
    public Condition newCondition() {
        return mainLock.newCondition();
    }
}

The advantages to this approach are that the class implements Java's Lock interface, and Condition Variables thus come with it in order to allow the creation of Monitors. Monitors are important in order to fully leverage locks for concurrent programming.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM