How to implement Lock only with AtomicInteger?

During the interview I was asked the following question:

How to implement an interface Lockif we have all parallel primitives AtomicInteger. That is, no synchronized, volatilevariables java util.concurrent, etc.

Of course, the first thing I thought was something like the following:

public static class ReentrantLock{
    private final AtomicInteger locked= new AtomicInteger();
    public void lock(){
        if(!locked.compareAndSet(0, 1))
            //throw new LockedException
    }

    public void unlock(){
        if(!locked.compareAndSet(1, 0))
            //throw new NotLockedException
    }
}

But this implementation cannot track Threadwhich acquired the lock. Any ideas how to implement it with just help AtomicInteger? With sun.misc.Unsafeit is possible, but what about without use Unsafe?

The problem is that we cannot track the current thread and change the field lockedatomically.

+4
source share
2 answers

, Thread.currentThread().getId() AtomicInteger, threadId. threadId threadId , , .

+3

, :

class AtomicIntegerLock {
    private final AtomicInteger token = new AtomicInteger(0);
    private Thread owner;

    public void lock() {
        while (!token.compareAndSet(0, 1)) {
            Thread.yield();
        }
        owner = Thread.currentThread();
    }

    public void unlock() {
        if (owner == Thread.currentThread()) {
            owner = null;
            token.set(0);
        } else {
            throw new IllegalMonitorStateException();
        }
    }
}

, owner , , . , .

() .

+1

Source: https://habr.com/ru/post/1687747/


All Articles