利用aqs构建一个自己的非公平独占锁

功能

具备基本的加锁、解锁功能,并且是非公平的(即允许插队)。

代码

java 复制代码
import java.util.concurrent.locks.AbstractQueuedSynchronizer;

public class MyNonfairLock {
    // 内部同步器类
    private static class Sync extends AbstractQueuedSynchronizer {
        // 尝试获取锁
        @Override
        protected boolean tryAcquire(int acquires) {
            // 非公平锁直接尝试获取,不考虑队列中是否有等待线程
            final Thread current = Thread.currentThread();
            int c = getState();
            if (c == 0) {
                // CAS 操作尝试获取锁
                if (compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            // 可重入支持
            else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;
                if (nextc < 0) // overflow
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }

        // 尝试释放锁
        @Override
        protected boolean tryRelease(int releases) {
            int c = getState() - releases;
            if (Thread.currentThread() != getExclusiveOwnerThread())
                throw new IllegalMonitorStateException();
            boolean free = false;
            if (c == 0) {
                free = true;
                setExclusiveOwnerThread(null);
            }
            setState(c);
            return free;
        }

        // 是否被当前线程独占
        @Override
        protected boolean isHeldExclusively() {
            return getExclusiveOwnerThread() == Thread.currentThread();
        }
    }

    // 创建同步器实例
    private final Sync sync = new Sync();

    // 加锁方法
    public void lock() {
        sync.acquire(1);
    }

    // 尝试加锁
    public boolean tryLock() {
        return sync.tryAcquire(1);
    }

    // 解锁方法
    public void unlock() {
        sync.release(1);
    }

    // 查询当前线程是否持有锁
    public boolean isHeldByCurrentThread() {
        return sync.isHeldExclusively();
    }

    // 查询锁是否被任何线程持有
    public boolean isLocked() {
        return sync.getState() != 0;
    }
}
  1. 非公平性实现:

在 tryAcquire 方法中,直接尝试获取锁(通过 CAS 操作),不考虑等待队列中是否有其他线程在等待

这与公平锁的区别在于公平锁会先检查队列中是否有等待线程

  1. 可重入支持:

如果当前线程已经是锁的持有者,则增加 state 计数

释放锁时需要释放相同次数

  1. 状态管理:

state = 0 表示锁未被占用

state > 0 表示锁被占用,且数值表示重入次数

  1. 独占模式:

只允许一个线程持有锁

使用 setExclusiveOwnerThread 和 getExclusiveOwnerThread 来跟踪锁的持有者

使用示例

java 复制代码
public class MyLockExample {
    private static final MyNonfairLock lock = new MyNonfairLock();
    private static int counter = 0;

    public static void main(String[] args) throws InterruptedException {
        Runnable task = () -> {
            for (int i = 0; i < 10000; i++) {
                lock.lock();
                try {
                    counter++;
                } finally {
                    lock.unlock();
                }
            }
        };

        Thread t1 = new Thread(task);
        Thread t2 = new Thread(task);

        t1.start();
        t2.start();
        t1.join();
        t2.join();

        System.out.println("Final counter value: " + counter); // 应该输出20000
    }
}
相关推荐
武子康41 分钟前
Java-82 深入浅出 MySQL 内部架构:服务层、存储引擎与文件系统全覆盖
java·开发语言·数据库·学习·mysql·spring·微服务
Rancemy41 分钟前
rabbitmq 03
java·分布式·rabbitmq
Dcs3 小时前
“SQL注入即服务”:一个10年历史系统的奇幻演变
java
秃了也弱了。3 小时前
reflections:Java非常好用的反射工具包
java·开发语言
Amagi.4 小时前
Java设计模式-代理模式
java·代理模式
Joker—H4 小时前
【Java】Reflection反射(代理模式)
java·开发语言·经验分享·代理模式·idea
阿里巴巴淘系技术团队官网博客4 小时前
面向互联网2C业务的分布式类Manus Java框架
java·开发语言·分布式
躲在云朵里`5 小时前
Java面试题(中等)
java
懂得节能嘛.5 小时前
【SpringAI实战】实现仿DeepSeek页面对话机器人(支持多模态上传)
java·spring
张乔245 小时前
mybatisX的自定义模板生成
java·ide·intellij-idea