独占锁demo,基本模仿ReentrantLock:
package com.example.springboot.codedemo; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.AbstractQueuedSynchronizer; import java.util.concurrent.locks.Condition; /** * 自定义一个独占锁,这里用公平锁 */ public class Mutex { /** * 静态内部类sync,间接操作AQS */ private final Sync sync; /** * 默认构造方法 */ public Mutex() { sync = new Sync(); } private static class Sync extends AbstractQueuedSynchronizer { /** * 当状态为0的时候,尝试获取锁 * * @param arg * @return */ @Override protected boolean tryAcquire(int arg) { //尝试获取同步状态并设值 if (compareAndSetState(0, 1)) { //设置当前的线程 setExclusiveOwnerThread(Thread.currentThread()); return true; } return false; } /** * 释放锁,并将状态设为0 * * @param arg * @return */ @Override protected boolean tryRelease(int arg) { //做个状态的判断 if (getState() == 0) { throw new IllegalMonitorStateException(); } //把占用线程置为null setExclusiveOwnerThread(null); //状态重新设为0 setState(0); return true; } /** * 判断是否处于独占状态 * * @return */ @Override protected boolean isHeldExclusively() { return getState() == 1; } /** * 返回一个Condition,每个Condition中都包含了一个Condition队列 * * @return */ final ConditionObject newCondition() { return new ConditionObject(); } } /** * 加锁方法 */ public void lock() { sync.acquire(1); } /** * 尝试获取锁的方法 */ public boolean tryLock() { return sync.tryAcquire(1); } /** * 解锁方法 */ public void unlock() { sync.release(1); } /** * 返回线程等待队列 * * @return */ public Condition newCondition() { return sync.newCondition(); } /** * 只要状态等于1,就代表同步状态已经被占用 * * @return */ public boolean isLocked() { return sync.isHeldExclusively(); } /** * 判断当前线程是否是队列中的第一个,true则不是,false则是 * * @return */ public boolean hasQueuedPredecessors() { return sync.hasQueuedPredecessors(); } /** * 支持超时时间获取锁 * * @param timeout * @param timeUnit * @throws InterruptedException */ public void tryLock(long timeout, TimeUnit timeUnit) throws InterruptedException { sync.tryAcquireNanos(1, TimeUnit.NANOSECONDS.toNanos(timeout)); } /** * 支持获取锁中断 * * @throws InterruptedException */ public void tryInterruptibly() throws InterruptedException { sync.acquireInterruptibly(1); } }测试代码:
public static void main(String[] args) { Mutex mutex = new Mutex(); //线程一 new Thread(() -> { System.out.println(Thread.currentThread().getName() + "准备获取锁"); mutex.lock(); try { System.out.println(Thread.currentThread().getName() + "获取到锁"); try { //睡眠一秒,方便看到效果 TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } finally { System.out.println(Thread.currentThread().getName() + "释放锁"); mutex.unlock(); } }, "线程一").start(); //线程二 new Thread(() -> { System.out.println(Thread.currentThread().getName() + "准备获取锁"); mutex.lock(); try { System.out.println(Thread.currentThread().getName() + "获取到锁"); } finally { System.out.println(Thread.currentThread().getName() + "释放锁"); mutex.unlock(); } }, "线程二").start(); }测试结果: 可以看到,效果和ReentrantLock基本相似。