如何仅使用AtomicInteger实现Lock?

时间:2017-10-18 19:25:10

标签: java multithreading

在求职面试中,我被问到以下问题:

如果我们拥有的所有并发原语都是Lock,如何实现AtomicInteger接口。即没有synchronized阻止,volatile变量java util.concurrent等等......

当然,我认为的第一件事就像下面这样:

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
    }
}

但是这种实现无法跟踪获得锁定的Thread。有关如何使用AtomicInteger实现它的任何想法?使用sun.misc.Unsafe是可能的,但如果不使用Unsafe呢?

问题是我们无法跟踪当前线程并以原子方式更改字段locked

2 个答案:

答案 0 :(得分:3)

也许您也可以使用Thread.currentThread().getId()获取调用线程的唯一ID,并将其设置为名为threadId的静态AtomicInteger。如果当前threadId与您的threadId相同,您可以决定该怎么做。

答案 1 :(得分:1)

我认为以下是非重入锁定的技巧:

Traceback (most recent call last):
  File "<pyshell#0>", line 1, in <module>
    from pymouse import PyMouse
  File "/usr/local/lib/python2.7/dist-packages/pymouse/__init__.py", line 41, in <module>
from .x11 import PyMouse, PyMouseEvent
  File "/usr/local/lib/python2.7/dist-packages/pymouse/x11.py", line 16, in <module>
    from Xlib.display import Display
  File "/usr/local/lib/python2.7/dist-packages/Xlib/display.py", line 26, in <module>
from six import create_unbound_method
ImportError: cannot import name create_unbound_method

虽然最初可能会认为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(); } } } 字段需要是不稳定的,但事实证明这不是必需的。在相同线程上的操作关系之前发生,确保调用者看到一致的值。

根据相同的逻辑,您可以添加(非易失性)计数器字段以使锁可重入。