首页 > 其他分享 >ReentrantLock分为公平锁和非公平锁,那底层分别是如何实现的

ReentrantLock分为公平锁和非公平锁,那底层分别是如何实现的

时间:2024-05-11 16:09:30浏览次数:13  
标签:Thread 队列 ReentrantLock 获取 线程 公平 底层

ReentrantLock在Java中是通过AbstractQueuedSynchronizer(AQS)框架实现的,它提供了公平锁(FairSync)和非公平锁(NonfairSync)两种模式。这两种锁的实现主要区别在于获取锁的策略。

import java.util.concurrent.locks.ReentrantLock;

public class ReentrantLockDemo {

    // 非公平锁
private static final ReentrantLock nonFairLock = new ReentrantLock();

    // 公平锁
private static final ReentrantLock fairLock = new ReentrantLock(true); // 传入true参数表示使用公平锁

public static void main(String[] args) {
        //demonstrateLock(nonFairLock, "Non-Fair Lock");
demonstrateLock(fairLock, "Fair Lock");
    }

    private static void demonstrateLock(ReentrantLock lock, String lockType) {
        class Task implements Runnable {
            @Override
            public void run() {
                for (int i = 0; i < 5; i++) {
                    lock.lock();
                    try {
                        System.out.println(Thread.currentThread().getName() + " acquired " + lockType + ", iteration: " + i);
                        Thread.sleep(10); // 模拟持有锁时的工作
} catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    } finally {
                        lock.unlock();
                    }
                }
            }
        }

        Thread t1 = new Thread(new Task(), "Thread-1");
        Thread t2 = new Thread(new Task(), "Thread-2");

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

        try {
            t1.join(); // 等待所有线程完成
t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

 公平锁(FairSync)的实现:

公平锁在尝试获取锁时,会首先检查队列中是否有其他等待的线程。如果有其他线程已经在等待队列中,那么新来的线程就会加入到队列的末尾排队等待,而不是尝试直接获取锁。这样可以确保线程按照它们请求锁的顺序来获取锁,体现了公平性。公平锁的实现步骤大致如下:

1. 调用`lock()`方法时,首先通过CAS操作尝试快速获取锁。
2. 如果失败,检查AQS的等待队列中是否已经有线程在等待。如果有,当前线程就加入到队列末尾等待,不会进行进一步的尝试。
3. 当前线程会进入阻塞状态,直到被AQS唤醒,通常是前一个持有锁的线程释放锁并唤醒它。

### 非公平锁(NonfairSync)的实现:

非公平锁在尝试获取锁时,不管队列中是否有其他线程在等待,总是会先尝试直接通过CAS操作快速获取锁,这可能导致新来的线程“插队”,获得锁的机会优于已经在队列中等待的线程。这种设计牺牲了公平性以换取更高的吞吐量。非公平锁的实现步骤大致如下:

1. 在`lock()`方法中,同样首先尝试通过CAS操作快速获取锁,即使此时有其他线程已经在队列中等待。
2. 如果快速获取失败,非公平锁仍然可能会继续尝试CAS获取锁,即使队列中已有等待线程。这意味着它可能在某些情况下直接获取锁,跳过队列中的其他线程。
3. 只有当多次尝试CAS获取锁都失败后,才会将当前线程加入到等待队列,并进入阻塞状态。

无论是公平锁还是非公平锁,它们都使用了AQS的内部FIFO队列来管理等待的线程,以及通过状态位(state)和等待节点(Node)来协调线程的阻塞与唤醒。此外,ReentrantLock还支持可重入特性,即已经持有锁的线程再次请求相同锁时可以直接获取,而不需要再次排队。

标签:Thread,队列,ReentrantLock,获取,线程,公平,底层
From: https://www.cnblogs.com/89564f/p/18186675

相关文章

  • 顶层const和底层const
    什么是顶层const和底层const顶层const:表示指针是一个常量。底层const:表示指针所指向的对象是一个常量。1、例子指针中constconstint*constp=newint(10);第一个const是底层const,第二个是顶层const。普通变量中constconstinta=10;intconstb=10;......
  • Redisson的看门狗机制底层实现
    1.看门狗机制概述看门狗机制是Redission提供的一种自动延期机制,这个机制使得Redission提供的分布式锁是可以自动续期的。privatelonglockWatchdogTimeout=30*1000;1看门狗机制提供的默认超时时间是30*1000毫秒,也就是30秒如果一个线程获取锁后,运行程序到释放锁所花费的时......
  • MyBatis学习总结 + 【手写MyBatis底层机制核心】
    MyBatis笔记MyBatis介绍MyBatis是一个持久层框架前身是ibatis,在ibatis3.x时,更名为MyBatisMyBatis在java和sql之间提供更灵活的映射方案mybatis可以将对数据表的操作(sql,方法)等等直接剥离,写到xml配置文件,实现和java代码的解耦mybatis通过SQL操作DB,建库建表......
  • 搞IT的为什么不建议搞底层(编译器、编程语言、)——当你搬进你的新家之后,你会在意这个楼
    文字表达引自:https://www.youtube.com/watch?v=KITqGv1qYg8当你搬进你的新家之后,你会在意这个楼是谁打的地基吗?你猜猜那些打地基的工人赚多少钱,卖你沙发电视机微波炉的人赚多少钱,当你在你温馨的小家里舒适的生活的时候,你会想这地基打的真好吗,只有一种情况下你会想到地基的事,就......
  • 底层架构
    一:角色分类(1)Coordinator协调器:协调器服务监视数据服务器上的历史服务。他们负责将区段分配给特定服务器,并确保区段在历史服务器之间保持良好的平衡。(2)Overlord:控制数据摄入任务的分配,Overlord服务监视数据服务器上的MiddleManager服务,并且是将数据摄取到Druid。他们负......
  • 蚂蚁面试:Springcloud核心组件的底层原理,你知道多少?
    文章很长,且持续更新,建议收藏起来,慢慢读!疯狂创客圈总目录博客园版为您奉上珍贵的学习资源:免费赠送:《尼恩Java面试宝典》持续更新+史上最全+面试必备2000页+面试必备+大厂必备+涨薪必备免费赠送:《尼恩技术圣经+高并发系列PDF》,帮你实现技术自由,完成职业升级,薪......
  • Mysql锁机制与优化实践以及MVCC底层原理剖析
    学习来源-图灵课堂https://vip.tulingxueyuan.cn锁学习参考:https://juejin.cn/post/7307889500545253395  锁机制为了保证数据的一致性,当访问共享变量的时候我们可以针对共享数据加锁,但是加锁要时要注意加锁的成本,还有加锁的粒度,还有就是是否会发生死锁,还有就是发生了死锁......
  • 大厂50万节点监控系统架构设计&Prometheus底层源码级剖析
    大厂50万节点监控系统架构设计&Prometheus底层源码级剖析 设计和实现一个大规模监控系统需要深入考虑架构设计、可伸缩性、性能优化等方面。下面是一个关于大规模监控系统架构设计的简要指南,以及有关Prometheus底层源码的剖析:大规模监控系统架构设计:1.架构设计原......
  • python将图片添加到视频底层中(提高处理单个视频的效率)
    代码: importcv2importnumpyasnpimportosimportrandomfromconcurrent.futuresimportThreadPoolExecutor#图片文件夹路径image_folder_path=r'F:\jingguan\tu'#视频文件所在的文件夹路径video_folder_path=r'F:\jingguan\yuan'#输出视频文件夹路径ou......
  • python将图片添加到视频底层中
    代码:importcv2importnumpyasnpimportosimportrandom#图片文件夹路径image_folder_path='path_to_your_images_folder'#视频文件所在的文件夹路径video_folder_path='path_to_your_videos_folder'#输出视频文件夹路径(如果不存在则创建)output_folder_pat......