在求职面试中,我被问到以下问题:
如果我们拥有的所有并发原语都是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
。
答案 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();
}
}
}
字段需要是不稳定的,但事实证明这不是必需的。在相同线程上的操作关系之前发生,确保调用者看到一致的值。
根据相同的逻辑,您可以添加(非易失性)计数器字段以使锁可重入。