
ReentrantLock底层原理、手写Lock锁
队列处理优化:使用无参的 唤醒批量处理:同时唤醒多个等待线程,减少时间 wasting。 自旋机制:优化自旋队列,提升抢锁效率。 防饥饿机制:在高并发下,增加公平锁的实现。
发布日期:2021-05-14 12:39:13
浏览次数:16
分类:精选文章
本文共 3499 字,大约阅读时间需要 11 分钟。
ReentrantLock 是一种轻量级锁,由 Java 自行实现,采用自旋锁的原理,无需依赖操作系统。在 JDK 1.5 以前,synchronized 锁较重,效率较低。而 ReentrantLock 则更高效,支持递归。以下是自定义实现 ReentrantLock 的过程:
自定义锁实现
首先,创建一个名为 XdLock 的类,实现 Lock 接口。使用 AtomicReference 记录持有锁的线程,LinkedBlockingQueue 缓存等待线程。
package com.test;import java.util.concurrent.LinkedBlockingQueue;import java.util.concurrent.TimeUnit;import java.util.concurrent.atomic.AtomicReference;public class XdLock implements Lock { private AtomicReferencecas; private final LinkedBlockingQueue queue; public XdLock() { cas = new AtomicReference<>(); queue = new LinkedBlockingQueue<>(); } @Override public void lock() { final Thread current = Thread.currentThread(); while (!cas.compareAndSet(null, current)) { // 进入队列 queue.put(current); System.out.println(current.getName() + ":进入阻塞"); LockSupport.park(); System.out.println(current.getName() + ":已放开阻塞线程"); // 唤醒时处理 boolean unwrapped = true; while (unwrapped) { unwrapped = queue.poll() != null; if (unwrapped) { LockSupport.unpark(unwrapped); } } } } @Override public void unlock() { final Thread current = Thread.currentThread(); if (cas.compareAndSet(current, null)) { // 唤醒队列中的所有线程 for (Thread t : new LinkedHashSet<>(queue)) { System.out.println(getCurrent().getName() + ":唤醒线程 " + t.getName()); LockSupport.unpark(t); } // 重置队列为空 queue.clear(); } } @Override public Condition newCondition() { return null; // 简化实现,留空或自定义条件处理 } // 提供不尝试锁的新方法 @Override public boolean tryLock() { return false; // 简化实现 } // 支持锁的可中断性,但此处简化 @Override public void lockInterruptibly() throws InterruptedException { // 类似 lock(),直接进入阻塞 } // 提供时限的锁获取方式 @Override public boolean tryLock(final long time, final TimeUnit unit) throws InterruptedException { return false; } // 辅助获取当前线程 private static Thread getCurrent() { return Thread.currentThread(); }}
测试实现
编写测试代码,观察多线程行为。
public class LockTest { private static XdLock lock; public static void main(String[] args) { lock = new XdLock(); Runnable task = () -> { try { lock.lock(); System.out.println(Thread.currentThread().getName() + ":获取锁成功"); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(getCurrent().getName() + ":解锁成功"); } finally { lock.unlock(); } }; long start = System.currentTimeMillis(); for (int i = 0; i < 5; i++) { new Thread(task).start(); if (i > 0) Thread.sleep(100); } System.out.println("总耗时:" + (System.currentTimeMillis() - start)); } private static Thread getCurrent() { return Thread.currentThread(); }}
优化考虑
_BLK
队列,提高性能。结论
通过上述实现,理解了 ReentrantLock 的原理,掌握了轻量级锁的开发技巧。这不仅增进了对 Java 并发编程的理解,还为后续项目提供了实用的开发经验。对于高并发场景,需结合具体需求选择合适的锁机制,以确保程序高效稳定运行。
发表评论
最新留言
逛到本站,mark一下
[***.202.152.39]2025年04月30日 00时19分10秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
算法训练 完数(循环,数学知识)
2019-03-11
什么是接口
2019-03-11
2020版nodejs12.18.3安装配置教程
2019-03-11
iview组件库中,Form组件里的Input,无法正确绑定on-enter事件
2019-03-11
记录-基于springboot+vue.js实现的超大文件分片极速上传及流式下载
2019-03-11
JavaScript高级程序设计第四版学习记录-第九章代理与反射
2019-03-11
怎么解决Windows 10文件/文件夹正在使用无法删除
2019-03-11
F28335第九篇——通用IO
2019-03-11
STM32F429第十一篇之数据类型
2019-03-11
web项目开发记录
2019-03-11
matlab函数:sprintf详解
2019-03-11
matlab函数:fix 向0取整
2019-03-11
ORCAD创建元件库时,格点对不起怎么办
2019-03-11
Allegro中如何消除器件本身Pin间距报错
2019-03-11
AD中拖动器件,无法移动在一起如何解决
2019-03-11
linux--练习001-基础类型
2019-03-11
python内存地址和编译字节码
2019-03-11
Flask--简介
2019-03-11
Flask模板--过滤器与测试器
2019-03-11
16 python基础-恺撒密码
2019-03-11