import sun.misc.Unsafe;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.locks.LockSupport;
public class MyLock {
private static final Unsafe unsafe = UnSafeInstance.refkectGetUnSafe();
private static long staticOffset;
static {
try {
staticOffset = unsafe.objectFieldOffset(MyLock.class.getDeclaredField("status"));
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
private volatile int status = 0;
private Thread lockHolder;
public int getStatus() {
return status;
}
public Thread getLockHolder() {
return lockHolder;
}
public void setStatus(int status) {
this.status = status;
}
public void setLockHolder(Thread lockHolder) {
this.lockHolder = lockHolder;
}
private ConcurrentLinkedQueue<Thread> waiters = new ConcurrentLinkedQueue<>();
public void lock() {
if (acquire()) {
return;
}
Thread currentThread = Thread.currentThread();
waiters.add(currentThread);
for (; ; ) {
if ((currentThread == waiters.peek()) && acquire()) {
waiters.poll();
return;
}
LockSupport.park(currentThread);
}
}
private boolean acquire() {
Thread currentThread = Thread.currentThread();
int c = getStatus();
if (c == 0) {
if ((waiters.size() == 0 || currentThread == waiters.peek()) && compareAndSwapStatus(0, 1)) {
setLockHolder(currentThread);
return true;
}
}
return false;
}
private final boolean compareAndSwapStatus(int except, int update) {
return unsafe.compareAndSwapInt(this, staticOffset, except, update);
}
public void unlock() {
if (Thread.currentThread() != getLockHolder()) {
throw new RuntimeException("not current thread");
}
int c = getStatus();
if (compareAndSwapStatus(c, 0)) {
setLockHolder(null);
Thread first = waiters.peek();
if (first != null) {
LockSupport.unpark(first);
}
}
}
}
import java.lang.reflect.Field;
import sun.misc.Unsafe;
public class UnSafeInstance {
public static Unsafe refkectGetUnSafe() {
try {
Field filed = Unsafe.class.getDeclaredField("theUnsafe");
filed.setAccessible(true);
return (Unsafe) filed.get(null);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}