public class SpinLock implements Lock {
private final AtomicReference<Thread> owner = new AtomicReference<Thread>();
private AtomicInteger holdCount = new AtomicInteger(1);
public void lock() {
if (owner.get() == Thread.currentThread()) {
holdCount.incrementAndGet();
return ;
}
while (!owner.compareAndSet(null, Thread.currentThread())) {
}
holdCount.set(1);
}
public void lockInterruptibly throws InterruptedException {
if (owner.get() == Thread.currentThread()) {
holdCount.incrementAndGet();
return ;
}
while (!(owner.compareAndSet(null, Thread.currentThread()))) {
if (owner.isInterrupted()) {
owner.interrupt();
}
}
holdCount.set(1);
}
public boolean tryLock() {
if (owner == Thread.currentThread()) {
holdCount.incrementAndGet();
return true;
}
boolean flag = owner.compareAndSet(null, Thread.currentThread());
if (flag) {
holdCount.set(1);
}
return flag;
}
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
if (owner == Thread.currentThread()) {
holdCount.incrementAndGet();
return true;
}
long start = System.nanoTime();
long timeout = unit.toNanos(time);
while (!owner.compareAndSet(null, Thread.currentThread)) {
if (owner.isInterrupted()) {
owner.interrupt();
}
long elapsedTime = System.nanoTime() - start;
if (elapsedTime >= timeout) {
return false;
}
}
holdCount.set(1);
return true;
}
public void unlock() {
if (owner != Thread.currentThread())
throw new IllegalMonitorStateException();
if (--holdCount == 0) {
owner.set(null);
}
}
}