Java 魔法类 Unsafe 源码解读(一)

news2024/11/17 17:54:53

Java 魔法类 Unsafe 源码解读(一)

前言

阅读过 JUC 源码的同学,一定会发现很多并发工具都调用了一个叫做 Unsafe 的类。

那这个类的作用是什么呢?有什么使用场景呢?底层源码是什么样呢?这篇文章笔者就带你搞清楚!

本文章所使用的是 JDK11 。不同于市面上大部分的文章所使用的JDK8

希望各位在阅读我这篇文章时,静下心来,逐字逐句的阅读!

同时建议大家可以点开 Unsafe 这个类,跟着我的文章一起深入它


一、Unsafe 介绍

Unsafe 是位于 sum.misc 包下的一个类(其实真正的 Unsafe 是位于 jdk.internal.misc 包下的,笔者后面会说到。)主要提供一些用于执行低级别、不安全操作的方法,如直接访问系统内存资源、自主管理内存资源等,这些方法在提升 Java 运行效率、增强 Java 语言底层资源操作能力方面起到了很大的作用。但由于 Unsafe 类使 Java 语言拥有了类似 C 语言指针一样操作内存空间的能力,这无疑也增加了程序发生相关指针问题的风险。

在程序中过度、不正确使用 Unsafe 类会使得程序出错的概率变大,使得 Java 这种安全的语言变得不再“安全”,因此对 Unsafe 的使用一定要慎重!

另外,Unsafe 提供的这些功能的实现需要依赖本地方法(Native Method)。

  • 什么是本地方法? -> 本地方法可以看作是 Java 中使用其他编程语言编写的方法。本地方法使用 native 关键字修饰,Java 代码中只是声明方法头,具体的实现则交给本地代码。
    在这里插入图片描述

扩展:

为什么要使用本地方法呢?
	1.需要用到 Java 中不具备的依赖于操作系统的特性,Java 在实现跨平台的同时要实现对底层的控制,需要借助其他语言发挥作用。
	2.对于其他语言已经完成的一些现成功能,可以使用 Java 直接调用。
	3.程序对时间敏感或对性能要求非常高时,有必要使用更加底层的语言,例如 C/C++甚至是汇编。
	
在 JUC 包的很多并发工具类在实现并发机制时,都调用了本地方法,通过它们打破了 Java 运行时的界限,能够接触到操作系统底层的某些功能。对于同一本地方法,不同的操作系统可能会通过不同的方式来实现,但是对于使用者来说是透明的,最终都会得到相同的结果。

二、Unsafe 创建

首先,我们从 Unsafe 类的定义来解读源码。

public final class Unsafe {

    // 静态代码块,会在程序启动时最先执行且只会执行一次。
    // 目的不明,要是有知道的大佬可以解答下!!!
    static {
        Reflection.registerMethodsToFilter(Unsafe.class, "getUnsafe");
    }

    private Unsafe() {}
	
    // 单例对象  饿汉式单例
    private static final Unsafe theUnsafe = new Unsafe();
    private static final jdk.internal.misc.Unsafe theInternalUnsafe = jdk.internal.misc.Unsafe.getUnsafe();

    // 核心代码!
    @CallerSensitive  
    public static Unsafe getUnsafe() {
        // 返回调用此方法的调用者的类
        Class<?> caller = Reflection.getCallerClass();
        // 仅在引导类加载器 BootstrapClassLoader 或平台类加载器 PlatformClassLoader 加载时才合法
        if (!VM.isSystemDomainLoader(caller.getClassLoader()))
            throw new SecurityException("Unsafe");  // 如果调用者类的类加载器不在授予所有权限的系统域中,抛出此异常。
        return theUnsafe;
    }
}

// 如果给定的类加载器是引导类加载器 BootstrapClassLoader 或平台类加载器 PlatformClassLoader,则返回true。
public static boolean isSystemDomainLoader(ClassLoader loader) {
    // ClassLoader最上方的类定义中规定了 BootstrapClassLoader 和 PlatformClassLoader 的定义
    // BootstrapClassLoader:它是虚拟机的内置类加载器,通常表示为null,并且没有父类。
    // PlatformClassLoader:所有平台类对于可用作ClassLoader实例父级的平台类加载器都是可见的。平台类包括Java SE平台API、它们的实现类和由平台类加载器或其祖先定义的JDK特定运行时类。
    return loader == null || loader == ClassLoader.getPlatformClassLoader();
}

Unsafe 类为饿汉单例实现,提供静态方法 getUnsafe 获取 Unsafe实例。这个看上去貌似可以用来获取 Unsafe 实例。但是,当我们直接通过 Unsafe.getUnsafe() 调用这个静态方法的时候,会抛出 SecurityException 异常!

// 这是因为 VM.isSystemDomainLoader() 进行了检查。
// 会对调用者的classLoader进行检查,判断当前类是否由 BootstrapClassLoader 加载,如果不是的话那么就会抛异常。
Exception in thread "main" java.lang.SecurityException: Unsafe  
 at sun.misc.Unsafe.getUnsafe(Unsafe.java:90)
 at com.cn.test.GetUnsafeTest.main(GetUnsafeTest.java:12

三、Unsafe 操作

Unsafe 的操作主要可以分为以下几类:

  1. 内存操作
  2. 内存屏障
  3. 对象操作
  4. 数据操作
  5. CAS 操作
  6. 线程调度
  7. Class 调度
  8. 系统信息

内存操作

Java 中是不允许直接对内存进行操作的,对象内存的分配和回收都是由 JVM 自己实现的(自动内存管理垃圾回收机制 GC)。

但是在 Unsafe 中,提供了以下几个接口来直接操作内存:

// 分配给定大小(以字节为单位)的新本地内存块
public long allocateMemory(long bytes);

// 将新的本地内存块调整为给定的字节大小。
public long reallocateMemory(long address, long bytes);

//将内存设置为指定值
public void setMemory(Object o, long offset, long bytes, byte value);

//内存拷贝
public void copyMemory(Object srcBase, long srcOffset,Object destBase, long destOffset,long bytes);

//清除内存
public void freeMemory(long address);

后记

剩下的内容,笔者会在三天内出完。各位可以期待下。这篇文章有学习JavaGuide的部分内容!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2087884.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

uni-app商城小程序+后台管理系统,手把手教你搭建

uni-app商城小程序是一种通过uni-app框架开发的&#xff0c;可以在微信、支付宝、字节跳动等多个平台上运行的轻量级电商应用。 一、特点 跨平台兼容&#xff1a;基于uni-app框架&#xff0c;一次开发&#xff0c;可同时适配微信小程序、支付宝小程序、H5、App等多个平台&…

3DMAX2025新款插件精选大全

关于3DMAX2025的新款插件&#xff0c;虽然无法提供一个详尽无遗的列表&#xff0c;本文根据公开发布的信息和插件的流行趋势&#xff0c;概述一些新款插件或插件更新。请注意&#xff0c;由于插件市场不断变化&#xff0c;以下信息可能随时间而有所更新。 以下插件按首字母排序…

ts转mp4怎么转?分享3个方法,快速搞定

在视频编辑和处理的世界里&#xff0c;格式转换是一个常见且必要的任务。特别是当你手头上有一些ts格式的视频文件&#xff0c;而你又需要将它们转换成更通用、更容易分享的mp4格式时&#xff0c;了解如何进行转换就显得尤为重要。 只有掌握了格式转换的技能&#xff0c;我们才…

yolov8训练野火烟雾识别检测模型

1.数据集下载 数据集下载链接&#xff1a;https://hyper.ai/datasets/33096 2. 数据集格式转换 需要将json中的标注信息转换为yolo格式的标注文件数据 import json import os import shutil import cv2 import matplotlib.pyplot as plttarget "./data/val" def…

如何在没有密码的情况下解锁 Oppo 手机?5 种简单的方法

保护智能手机隐私的一种很好的方法是设置复杂的锁屏密码或图案。一些 OPPO 手机的所有者在更改后一夜之间经历了图案或密码的内存丢失。事实上&#xff0c;OPPO 用户遇到的众多问题包括忘记密码或锁定屏幕。遗憾的是&#xff0c;没有多少人知道无需密码即可解锁 OPPO 手机的简单…

JAVA毕业设计166—基于Java+Springboot+vue3的流浪宠物救助管理小程序(源代码+数据库)

毕设所有选题&#xff1a; https://blog.csdn.net/2303_76227485/article/details/131104075 基于JavaSpringbootvue3的流浪宠物救助管理小程序(源代码数据库)166 一、系统介绍 本项目前后端分离带小程序(可以改为ssm版本)&#xff0c;分为用户、救助站、管理员三种角色 1、…

chapter09-OOP高级部分——(类变量和类方法)——day12

目录 ​编辑 374-类变量引出 375-类变量快速入门 376-类变量内存剖析 377-类变量定义访问 378-类变量使用细节 379-类方法快速入门 380-类方法最佳实践 381-类方法注意事项 静态方法只能访问静态变量 非静态方法可以访问静态成员和非静态成员&#xff08;都可以访问…

OpenAI AI 聊天机器人周活跃用户超 2 亿

&#x1f989; AI新闻 &#x1f680; OpenAI AI 聊天机器人周活跃用户超 2 亿 摘要&#xff1a;科技媒体 Axios 报道&#xff0c;OpenAI 的 AI 聊天机器人在短短一年内实现了周活跃用户超过 2 亿的增长。该公司表示&#xff0c;全球财富 500 强企业中已有 92% 使用其产品&…

革新客户服务艺术:揭秘高效集成第三方平台与质检升级的前沿策略

Hi~这里是ProXiao 文章参考&#xff1a;晓观点 如何实现与第三方客服平台的有效对接并提高客户服务的质检水平&#xff1f;https://insight.xiaoduoai.com/intelligent-tools/quality-inspection/how-to-achieve-effective-integration-with-third-party-customer-service-pl…

书法图片自动扣字的批处理

本程序会根据原文字图片&#xff0c;自动扣字并生成黑字、红字2个透明的png图片&#xff0c;原图片黑字或白字均可。运行的话需要先安装好 ImageMagick-7.1.1-37 用法与生成效果举例&#xff1a; a.jpg 白字 转 黑、红扣字png: b.jpg 黑字 转 黑、红扣字png: 分享脚本如下: …

Kafka 到数据仓库:使用 bend-ingest-kafka 将消息加载到 Databend

将消息从 Apache Kafka 导入到像 Databend 这样的云数据仓库可能是一项艰巨的任务。bend-ingest-kafka 工具简化了这一过程&#xff0c;使您能够轻松地将 Kafka 消息导入到 Databend 表中。 什么是 bend-ingest-kafka&#xff1f; bend-ingest-kafka 工具是一个专门为从 Apac…

网上一堆教人用AI做自媒体的,真的能挣钱吗?看我真实测评~

今日主题&#xff1a;AI副业能做吗&#xff1f; 今年这情况&#xff0c;几乎所有人都想搞个副业。 有人问我&#xff1a;普通人真的能靠AI做自媒体搞钱吗&#xff1f; 先说结论&#xff1a;可以&#xff0c;但要找准路子&#xff01; 听我慢慢道来~ 我是今年开始做AI自媒体…

同声传译用什么软件?5款优质软件评测

最近&#xff0c;我遇到了一个尴尬的情况。在一次国际会议中&#xff0c;我被分配到了一个多语言小组讨论。虽然我的英语还算流利&#xff0c;但面对来自世界各地的同事们&#xff0c;各种口音和语速让我感到有些力不从心。 那一刻&#xff0c;我多么希望有一个神奇的工具&…

如何解决已经安装软航文档控件但依旧提示未安装的问题

目录 前言 问题现象 问题处理步骤 前言 本文介绍在办公系统中使用重庆软航科技有限公司开发的NTKO OFFICE文档控件软件时&#xff0c;已经通过办公系统提供的软件安装包安装&#xff0c;但是在360安全浏览器、360极速浏览器的兼容模式下依旧提示&#xff1a;本机尚未安装跨浏…

STM32F411 标准库硬件SPI (硬件NSS/CS)驱动st7735--1.8寸TFT显示屏

TFT的spi驱动文件 完整工程网盘放在末尾 #include "lcd_driver.h"static uint16_t SPI_TIMEOUT_UserCallback(uint8_t errorCode);//液晶IO初始化配置 void LCD_Driver_Init(void) {SPI_InitTypeDef SPI_InitStructure;GPIO_InitTypeDef GPIO_InitStructure;/* 使能…

关于武汉芯景科技有限公司的实时时钟芯片XJ8340开发指南(兼容DS1340)

一、芯片引脚介绍 1.芯片引脚 2.引脚描述 二、系统结构图 三、功能描述 1.时钟功能 2.频率输出 / 普通IO口 FT/OUT引脚输出512HZ的方波或者高低电平 3.备用电源 4.涓流充电 5.振荡停止检测 四、程序代码 XJ8340.C /** XJ8340.c** Created on: 2024年8月29日* Auth…

萤石开放平台 播放报错4012,URL过期或无效

当你在尝试打开直播地址时&#xff0c;如果遇到了报错提示“4012&#xff0c;URL过期或无效&#xff0c;请检查URL的有效性”。 这通常表示直播地址中的UUID&#xff08;一个独特的识别码&#xff09;可能存在问题&#xff0c;例如过期或无权限访问。以下是一些排查及解决该问题…

【ACM独立出版 | 厦大主办】第五届计算机科学与管理科技国际学术会议(ICCSMT 2024,10月18-20)

第五届计算机科学与管理科技国际学术会议(ICCSMT 2024) 定于2024年10月18-20日在中国厦门举行。 会议旨在为从事“计算机科学”与“管理科技”研究的专家学者、工程技术人员、技术研发人员提供一个共享科研成果和前沿技术&#xff0c;了解学术发展趋势&#xff0c;拓宽研究思路…

Pandas 绘图的强大之处:后端

轻松通过 Pandas 创建交互式图形。欢迎来到雲闪世界。 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 1.背景 Python 有大量的可视化包&#xff0c;其中最有名的三个是&#xff1a;Matplotlib&#xff08;和 seaborn&#xff09;、Plotly和Hvplot。这三…

虚幻5|技能栏UI优化(2)——优化技能UI并实现技能栏的拖拽操作

这篇文章里&#xff0c;前情提要&#xff0c;文章里的序列变量应命名为序号&#xff0c;我命名错了&#xff0c;虽然不差&#xff0c;但为了后面更好的理解 一.刷新技能栏&#xff0c;用于刷新上一章文章的初始化技能栏 1.打开技能栏格子&#xff0c;打开图表&#xff0c;添加…