不可重入,公平锁
public class MyLock1 {
private Queue<Thread> queue = new ConcurrentLinkedQueue<>();
private final AtomicBoolean locked = new AtomicBoolean(false);
public void lock() {
final Thread current = Thread.currentThread();
boolean wasInterrupted = false;
queue.add(current);
for (;;) {
if (current == queue.peek() && locked.compareAndSet(false, true)) {
queue.remove();
if (wasInterrupted)
current.interrupt();
return;
}
LockSupport.park();
if (Thread.interrupted())
wasInterrupted = true;
}
}
public void unlock() {
locked.set(false);
LockSupport.unpark(queue.peek());
}
}
可重入锁, 非公平锁
public class MyReentrantLock {
private static final Unsafe unsafe = getUnsafe();
private Thread lockHolder;
private ConcurrentLinkedQueue<Thread> queue = new ConcurrentLinkedQueue<>();
private volatile int state;
private static final long stateOffset;
static {
try {
stateOffset = unsafe.objectFieldOffset(MyReentrantLock.class.getDeclaredField("state"));
} catch (Exception ex) {
throw new Error(ex);
}
}
protected final int getState() {
return state;
}
protected final void setState(int state) {
this.state = state;
}
protected final boolean compareAndSetState(int expect, int update) {
return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}
public Thread getLockHolder() {
return lockHolder;
}
public void setLockHolder(Thread lockHolder) {
this.lockHolder = lockHolder;
}
public boolean tryAcquire() {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (compareAndSetState(0, 1)) {
setLockHolder(current);
return true;
}
}
else if (current == getLockHolder()) {
int nextc = c + 1;
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
public boolean acquire() {
if (tryAcquire()) {
return true;
}
final Thread current = Thread.currentThread();
queue.add(current);
for (;;) {
if (current == queue.peek() && tryAcquire()) {
queue.poll();
return true;
}
LockSupport.park();
}
}
public void lock() {
if (compareAndSetState(0, 1)) {
setLockHolder(Thread.currentThread());
return;
}
acquire();
}
public void unlock() {
Thread current = Thread.currentThread();
if (current != lockHolder) {
throw new IllegalMonitorStateException("can't unlock");
}
int c = getState() - 1;
if (c == 0) {
setLockHolder(null);
}
setState(c);
Thread waiter = queue.peek();
if (null != waiter) {
LockSupport.unpark(waiter);
}
}
public static Unsafe getUnsafe() {
Unsafe unsafe = null;
try {
Constructor<Unsafe> constructor = Unsafe.class.getDeclaredConstructor(new Class<?>[0]);
constructor.setAccessible(true);
unsafe = constructor.newInstance(new Object[0]);
} catch (Exception e) {
e.printStackTrace();
}
return unsafe;
}
}
不可重入的锁,非公平锁
import java.lang.reflect.Constructor;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.locks.LockSupport;
import sun.misc.Unsafe;
public class MyLock {
private static final Unsafe unsafe = getUnsafe();
private Thread lockHolder;
private ConcurrentLinkedQueue<Thread> queue = new ConcurrentLinkedQueue<>();
private volatile int state;
private static final long stateOffset;
static {
try {
stateOffset = unsafe.objectFieldOffset(MyLock.class.getDeclaredField("state"));
} catch (Exception ex) {
throw new Error(ex);
}
}
protected final int getState() {
return state;
}
protected final boolean compareAndSetState(int expect, int update) {
return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}
public Thread getLockHolder() {
return lockHolder;
}
public void setLockHolder(Thread lockHolder) {
this.lockHolder = lockHolder;
}
private boolean tryAcquire() {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (compareAndSetState(0, 1)) {
setLockHolder(current);
return true;
}
}
return false;
}
private boolean acquire() {
if(tryAcquire()){
return true;
}
final Thread current = Thread.currentThread();
queue.add(current);
for (;;) {
if (current == queue.peek() && tryAcquire()) {
queue.poll();
return true;
}
LockSupport.park();
}
}
public void lock() {
if (compareAndSetState(0, 1)){
setLockHolder(Thread.currentThread());
return;
}
acquire();
}
public void unlock() {
Thread current = Thread.currentThread();
if (current != lockHolder) {
throw new RuntimeException("can't unlock");
}
if (compareAndSetState(1, 0)) {
lockHolder = null;
Thread waiter = queue.peek();
if (null != waiter) {
LockSupport.unpark(waiter);
}
}
}
public static Unsafe getUnsafe() {
Unsafe unsafe = null;
try {
Constructor<Unsafe> constructor = Unsafe.class.getDeclaredConstructor(new Class<?>[0]);
constructor.setAccessible(true);
unsafe = constructor.newInstance(new Object[0]);
} catch (Exception e) {
e.printStackTrace();
}
return unsafe;
}
}