使用Unsafe来实现自定义锁

1.使用Unsafe类

import sun.misc.Unsafe;

class UnsafePackage {
    private static Unsafe unsafe;

    static {
        try {
            Class<Unsafe> unsafeClass = Unsafe.class;
            Field theUnsafe = unsafeClass.getDeclaredField("theUnsafe");
            theUnsafe.setAccessible(true);
            unsafe = (Unsafe) theUnsafe.get(null);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public static Unsafe getUnsafe() {
        return unsafe;
    }
}

 

2.声明简单锁

class CustomLock {
    private volatile int status;

    private static Unsafe unsafe = UnsafePackage.getUnsafe();
    private static long statusOffset;
    private WaitingQueue queue = new WaitingQueue();

    static {
        try {
            statusOffset = unsafe.objectFieldOffset(CustomLock.class.getDeclaredField("status"));
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    private boolean comareAndSetStatus(int originalStatus, int updateStatus) {
        return unsafe.compareAndSwapInt(this, statusOffset, originalStatus, updateStatus);
    }

    public boolean lock() {
        if (comareAndSetStatus(0, 1)) {
            //System.out.println("竞争锁成功!继续执行后面的代码");
            return true;
        }

        //System.out.println("竞争锁失败!进入等待队列");
        push(Thread.currentThread());
        while (!comareAndSetStatus(0, 1)) {
            UnsafePackage.getUnsafe().park(false, 0);
        }
        return true;
    }

    public boolean unlock() {
        status = 0;
        Thread thread = pop();
        if (thread != null) {
            UnsafePackage.getUnsafe().unpark(thread);
        }
        return true;
    }

    private void push(Thread thread) {
        queue.push(thread);
    }

    private Thread pop() {
        return queue.pop();

    }
}

 

3.竞争锁失败的进队列

class WaitingQueue {
    private volatile int status;
    private static long statusOffset;

    /**
     * 非线程安全,使用时,也要加锁
     */
    private LinkedList<Thread> queue = new LinkedList<>();

    static {
        try {
            statusOffset = UnsafePackage.getUnsafe().objectFieldOffset(WaitingQueue.class.getDeclaredField("status"));
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public void push(Thread thread) {
        while (!comareAndSetStatus(0, 1)) {

        }
        queue.offerLast(thread);
        comareAndSetStatus(1, 0);
        return;
    }

    public Thread pop() {
        while (!comareAndSetStatus(0, 1)) {

        }
        Thread elem = null;
        if (!queue.isEmpty()) {
            elem = queue.pop();
        }
        comareAndSetStatus(1, 0);
        return elem;
    }

    private boolean comareAndSetStatus(int originalStatus, int updateStatus) {
        return UnsafePackage.getUnsafe().compareAndSwapInt(this, statusOffset, originalStatus, updateStatus);
    }
}

 

3.调用如下

public class CustomLockTest {


    private static int count = 0;

    public static void main(String[] args) throws InterruptedException {
        int threadCount = 1500;
        CountDownLatch countDownLatch = new CountDownLatch(threadCount);
        CustomLock lock = new CustomLock();
        long start = System.currentTimeMillis();
        IntStream.range(0, threadCount)
                .forEach(p -> {
                    new Thread() {
                        @Override
                        public void run() {
                            lock.lock();
                            try {
                                for (int i = 0; i < 1000; i++) {
                                    count++;
                                }
                                countDownLatch.countDown();
                            } finally {
                                lock.unlock();
                            }
                        }
                    }.start();
                });

        countDownLatch.await();
        long end = System.currentTimeMillis();
        System.out.println("结果值为:" + count + ",共花费了" + (end - start) + "毫秒!");
    }
}

 

结果值为:1500000,共花费了601毫秒!

 

转载于:https://www.cnblogs.com/zhshlimi/p/10919652.html

手把手入门YOLO到改进优化教程 | 【P2基础篇】数据标注+环境搭建+模型训练 本节以 YOLO自定义目标检测训练为主线,带你从零开始完成 数据标注 → 环境搭建 → 模型训练 → 结果的流程。使用labelImg制作符合YOLO格式的自定义数据集。在Windows基于 Python + Conda 创建独立虚拟环境,安装 PyTorch + CUDA + ultralytics,配置 PyCharm 运行环境。本节不仅使用自定义数据集进行演示,同时也用公开数据集训练 YOLO,查看训练日志与可视化结果(PR、P/R/F1 曲线等)等。 阅读详情

相关推荐

【java】 如何自己写一把多线程锁 上 创建 Unsafe类对象

1.先看lock接口 看下这个接口有几个方法等着我们重写 六个方法 加锁,尝试加锁,定时尝试加锁,解锁 主要是这是个方法 其他两个骚方法放一边 不玩这么骚的 2. 准备工作 创建一个类 我这里取名叫 MyReentrantLock 我的可重入锁 实现 lock接口 import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition; import java.util.concurrent.loc

纸上得来终觉浅,绝知此事要躬行 4569

ESP32蓝牙配网实战:微信小程序中的blufi协议实现与优化

本文详细介绍了在微信小程序中实现ESP32蓝牙配网的实战经验,重点解析了blufi协议的应用与优化。内容涵盖从开发环境配置、协议帧格式解析,到小程序端蓝牙通信、数据转换的核心步骤,并提供了配网状态机设计、错误处理及性能调优等进阶方案,旨在帮助开发者高效、稳定地完成物联网设备配网功能开发。

weixin_29159613的博客 455

java实践8各种锁的实现和解析(上篇)

锁 synchronized cas 自旋锁 可重入 锁 悲观锁 锁升级 等解析。

m252131895的博客 527

从2-RSS-1U并联踝关节到双足机器人动态行走:雅可比矩阵与力矩控制实践

本文深入探讨了2-RSS-1U并联踝关节在双足机器人动态行走中的关键作用,详细解析了其设计原理、雅可比矩阵的应用及力矩控制实践。通过优化几何参数和控制算法,实现了低转动惯量、高刚度和紧凑设计,显著提升了机器人的行走稳定性和能量效率。文章还分享了从仿真到实物的跨越经验及未来优化方向。

weixin_42641998的博客 594

SCL3400-D01双轴高精度倾角计

简介 两轴高精度加速度计,提供两个模式。 ±30° with 10 Hz LPF ±90° with 40 Hz LPF Resolution up to 32768 LSB/g Ultra-low 0.0009°/√Hz noise density 这款传感器是替换之前村田的停产的模拟量系列的芯片,正在测试中,具体效果大伙可以评测。 一、引脚连接图 引脚图兼容SCL3300 二、SPI接口 1.SCL3300和SCL3400略有区别如下图 左边为SCL3...

专注惯导领域 3808

UnSafe实现+CAS思想(自旋锁)

自旋锁:获取锁的线程不会立即阻塞,而是采用循环的方式去尝试获取锁,一直循环到获取锁为止。 非自旋锁: 获取不到锁,线程就进入阻塞状态。等待 CPU 唤醒,再去获取 想象以下场景:某线程去获取锁(可能是自旋锁 or 非自旋锁),然而锁现在被其他线程占用了。它两获取锁的执行流程就如下图所示: [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nx7IljzW-1650758877574)(https] 😕/img-blog.csdnimg.cn/5d49d27596c04b97ab2

weixin_46402513的博客 346

STM32开发者必看:如何在正点原子探索者开发板上快速移植CANopenNode协议栈

本文为STM32开发者提供了在正点原子探索者开发板上快速移植CANopenNode协议栈的实战指南。文章详细介绍了从环境准备、硬件抽象层适配到协议栈初始化与测试的全过程,并分享了PDO配置与性能优化等关键技巧,帮助开发者高效实现CANopen标准化通信。

weixin_29173777的博客 462

Java并发与锁设计实现详述(6)- 聊一聊Unsafe

UnSafe这个类是什么?我相信刚接触Java的人或者没有深入研究过Java的人应该都不会知道存在这个类。这个类是干嘛的呢?在讲并发的这个系列里为什么我要提它呢?答案很简单,那就是这个类对于并发非常重要,当然它的重要性不仅体现在对并发的支持上。之所以这篇文章说到UnSafe,是因为UnSafe类是同步队列器AbstractQueuedSynchronizer的重要组成部分,是AbstractQue...

马靖的个人技术博客 2698

Allegro File菜单实战指南:从导入网表到导出BOM的完整流程

PCB设计离不开对EDA软件菜单体系的深入理解。在Cadence Allegro中,File菜单是数据流转的中枢,它不仅是新建、打开、保存的基础入口,更是连接原理图与版图、设计与制造的关键桥梁。工程师常遇到的“导入网表报错”“导出BOM为空”“板框不闭合”等高频问题,大多源于对File菜单中Import与Export功能的理解不到位。从基础概念出发,先厘清Import(网表、DXF、IPC)与Export(BOM、ODB++、DXF)的工作原理,再结合版本兼容、封装库路径、单位设置等工程细节,即可构建完整的

weixin_32950759的博客 295

基于PChmi.dll的PLC报警显示和记录(C#)

本文介绍了如何使用C#编写基于PChmi.dll的程序,实现PLC报警的显示和记录功能。通过订阅PLC的报警事件,我们可以实时显示报警信息,并通过日志文件记录报警历史。PLC(可编程逻辑控制器)在工业自动化领域中扮演着重要的角色,而报警显示和记录是PLC应用中常见的需求。本文将介绍如何使用C#编写基于PChmi.dll的程序,实现PLC报警的显示和记录功能。当然,这只是实现报警显示和记录的基本框架,具体的实现方式可能因不同的PLC和HMI库而有所差异。你需要根据你所使用的具体库和设备进行相应的调整和修改。

ByteLegend的博客 1670

线程进阶:多任务处理(17)——Java中的锁(Unsafe基础)

1. 概述 本专题在之前的文章中详细介绍了Java中最常使用的一种锁机制——同步锁。但是同步锁肯定是不适合在所有应用场景中...

329

【Python基础】FastAPI 从入门到项目实战操作详解

【Python基础】FastAPI从入门到使用实战操作详解

congge_study的博客 437

CAS锁

package com.concurrent; import java.lang.reflect.Field; import java.util.concurrent.ConcurrentLinkedDeque; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; imp...

weixin_43326384的博客 199

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

线程安全锁代码实现

手动实现了一个线程安全的锁,希望对你有所帮助。 import sun.misc.Unsafe; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.locks.LockSupport; public class MyLock { private static final Un...

皮斯特劳沃 398

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

java 锁住变量_java同步之如何写一个锁Lock

问题(1)自己动手写一个锁需要哪些知识?(2)自己动手写一个锁到底有多简单?(3)自己能不能写出来一个完美的锁?简介本篇文章的目标一是自己动手写一个锁,这个锁的功能很简单,能进行正常的加锁、解锁操作。本篇文章的目标二是通过自己动手写一个锁,能更好地理解后面章节将要学习的AQS及各种同步器实现的原理。分析自己动手写一个锁需要准备些什么呢?首先,在上一章学习synchronized的时候我们说过它的实...

weixin_29290259的博客 865

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

java自定义锁_Java锁的实现

volatile属性:可见性、保证有序性、不保证原子性。Java的内存中所有的对象都存在主内存中,每个线程都有自己的栈和程序计数器,多个线程对同一个对象的变量读取时,会将对象的变量从主内存中拷贝到自己的栈帧里(操作数栈),线程之间也无法直接访问对方的操作数栈,只能通过主内存传递变量的值;可见性:如果对声明了volatile变量进行写操作时,JVM会向处理器发送一条Lock前缀的指令,将这个变量所在...

weixin_39812465的博客 380

Unsafe中的park和unpark

https://www.jianshu.com/p/15f33406543b

以爱护甲,爱满枫林。 2037

锁实现之初探一

锁的作用就是当一个线程持有锁的时候,其他线程都不能对锁定的共享变量进行操作,简而言之把并行操作变为串行操作。 用java如何实现,我们定义一个持有锁的标志,当一个线程持有锁的时候,把其他线程挂起,当这个持有锁的线程释放锁时,把其中一个的挂起的线程唤醒。 实现主要用到Unsafe的park方法挂起线程和unpark方法唤醒线程,java是不允许直接操作内存,所以这个类不能被直接引用,可以通过反射...

weixin_30394333的博客 96

实现一个简单的抽象队列同步器---理解AQS底层原理

AQS是 AbstractQueuedSynchronizer ,译为抽象的队列同步器。它主要为了保证我们高并发场景下的一个线程安全。这里我们通过自己实现一个简单版本的AQS来理解他的核心原理。 一、同步加锁思路 首先保证加锁的话,任意时刻只能是有一个线程加锁成功,也就是保证它的原子性。这里就提供一个 state 这样一个字段,来记录当前加锁的一个状态,也就是次数。我们要做的就是保证任意时刻,只有...

weixin_44058932的博客 382

分析一下优快云大佬写的CAS,可重入锁, 非公平锁

CAS,可重入锁, 非公平锁

打工仔~的博客 186

自旋+CAS实现java同步锁,代码存在很多问题

GetUnsafe: import sun.misc.Unsafe; import java.lang.reflect.Field; public class GetUnsafe { public static Unsafe getUnsafe(){ try { Field field=Unsafe.class.getDeclaredField(“theUnsafe”); field.setAcc...

qq_29055845的博客 323

Langfuse+Langchain+DeepSeek构建LLM实时对话监控仪表盘

在LLM应用大规模落地后,如何透视模型推理过程、定位错误根因并精确核算单次会话成本,成为工程实践中的核心难题。可观测性技术通过统一采集、关联与分析请求链路数据,为复杂系统提供透明化保障。Langfuse作为开源的全链路追踪平台,能够结构化记录提示词、模型输出及token消耗;结合Langchain的编排能力与DeepSeek的高效推理,可快速搭建一套低侵入的监控体系。通过WebSocket双向通信,仪表盘能实时渲染对话流中的token增量、响应耗时与trace链路,在性能调优、成本控制和质量回溯等场景中发挥

weixin_34099526的博客 259

队列同步器AQS

队列同步器AQS 实现自定义锁Lcck:(可参考ReentrantLock实现源码) class MutexDemo implements Lock, java.io.Serializable { ...

zxing的博客 279

Lock锁之公平锁与非公平锁(AQS实现原理)

在Concurrent包中的锁都是可重入锁,一般都命名为ReentrantX。可重入锁是指当一个线程调用object.lock拿到锁,进入互斥区后,再次调用object.lock,仍然可以拿到该锁。 synchtonized关键字就是可重入锁。

Fighting_Man的博客 4649

Java并发: 基于Unsafe的CAS实现无锁数据结构

为了方便测试和对比,我们事先定义了ID接口,里边只有一个方法incrementAndGet: 自增并返回int值。

你若盛开,清风自来 1266
上一篇: rabbitMQ实现推迟队列
下一篇: 使用join和CountDownLatch来等待线程结束
aiji7208
博客等级 码龄11年 2粉丝 0原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值