使用CAS写一个可重入锁

不可重入,公平锁

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) // reassert interrupt status on exit
					current.interrupt();
				return;
			}

			LockSupport.park();
			if (Thread.interrupted()) // ignore interrupts while waiting
				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<>();

	/**
	 * The synchronization state.
	 */
	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;
	}

	// CAS 以及 可重入逻辑
	public boolean tryAcquire() {
		final Thread current = Thread.currentThread();
		int c = getState();
		if (c == 0) {
			if (compareAndSetState(0, 1)) {
				setLockHolder(current);
				return true;
			}
		} 
		// reentrant
		else if (current == getLockHolder()) {
            int nextc = c + 1;
            if (nextc < 0) // overflow
                throw new Error("Maximum lock count exceeded");
            setState(nextc);
            return true;
        }
		return false;
	}

	public boolean acquire() {
		// try acquire
		if (tryAcquire()) {
			return true;
		}
		// add queue and spin
		final Thread current = Thread.currentThread();
		queue.add(current);
		for (;;) {
			if (current == queue.peek() && tryAcquire()) {// TODO CAS
				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);
		}
	}
	// unsafe util
	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<>();
	
	/**
	 * The synchronization state.
	 */
	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;
	}
	
	//TODO reentrant
	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() {
		//try acquire
		if(tryAcquire()){
			return true;
		}
        //add queue and spin
		final Thread current = Thread.currentThread();
        queue.add(current);
        for (;;) {
            if (current == queue.peek() && tryAcquire()) {//TODO CAS
            	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);
			}
		}
	}

	//unsafe util
	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;
	}
}

发布了327 篇原创文章 · 获赞 82 · 访问量 89万+

猜你喜欢

转载自blog.csdn.net/kkgbn/article/details/100136988
今日推荐