赞
踩
第一种
public class MyReentrantLock implements Lock { private Sync sync = new Sync(); @Override public void lock() { sync.acquire(1); } @Override public void lockInterruptibly() throws InterruptedException { sync.acquireInterruptibly(1); } @Override public boolean tryLock() { return sync.tryAcquire(1); } @Override public boolean tryLock(long time, TimeUnit unit) throws InterruptedException { return sync.tryAcquireNanos(1,time); } @Override public void unlock() { sync.release(1); } @Override public Condition newCondition() { return sync.newCondition(); } /** * AbstractQueuedSynchronizer,重写tryAcquire,tryRelease方法.就可以实现可重入独占锁。 */ public class Sync extends AbstractQueuedSynchronizer { /** * 尝试获取锁逻辑 * @param arg * @return */ @Override protected boolean tryAcquire(int arg) { // 0是上次的值,用来判断是都已经被修改,1要更新的值,compareAndSetState是AbstractQueuedSynchronizer类的方法,底层采用CAS自旋 if(compareAndSetState(0,1)){ setExclusiveOwnerThread(Thread.currentThread()); return true; } if(getExclusiveOwnerThread() == Thread.currentThread()){ setState(getState()+1); return true; } return false; } /** *尝试释放所 * @param arg * @return */ @Override protected boolean tryRelease(int arg) { if(getExclusiveOwnerThread()!= Thread.currentThread()){ throw new RuntimeException(); } int state = getState() - 1; // 减少可重入次数 if(state > 0){ setState(state); return false; } // 释放锁 setState(state); setExclusiveOwnerThread(null); return true; } Condition newCondition() { return new ConditionObject(); } } }
测试
public static void main(String[] args) {
MyReentrantLock myReentrantLock = new MyReentrantLock();
myReentrantLock.tryLock();
System.out.println("业务代码");
myReentrantLock.unlock();
System.out.println("第一次结束");
System.out.println("再来一次");
myReentrantLock.tryLock();
System.out.println("业务代码");
myReentrantLock.unlock();
System.out.println("第二次结束");
}
第二种
package lock; import java.util.concurrent.ConcurrentLinkedDeque; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.LockSupport; /** * @author lwh * @create 2023-02-26 11:08 */ public class MyLock { private AtomicInteger atomicInteger = new AtomicInteger(0); private Thread thread; // 存放阻塞的线程 ConcurrentLinkedDeque<Thread> concurrentLinkedDeque = new ConcurrentLinkedDeque<>(); public void lock(){ acquire(); } public boolean acquire() { for (;;){ // 自旋,死循环是为了唤醒后可以再获取锁, if (compareAndSet(0,1)) { // 获取到锁 thread = Thread.currentThread(); return true; } // 没获取到锁,进入队列,阻塞 Thread thread = Thread.currentThread(); concurrentLinkedDeque.add(Thread.currentThread()); LockSupport.park(thread); return false; } } public boolean compareAndSet(int expect, int update){ return atomicInteger.compareAndSet(expect,update); } public boolean unLock(){ if (thread == null) { return false; } if (thread == Thread.currentThread()) { boolean result = compareAndSet(1, 0); if (result) { Thread thread = concurrentLinkedDeque.getFirst(); // 公平锁唤醒阻塞的第一个线程 LockSupport.unpark(thread); return true; } } return true; } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。