Java基础之关键字

关键字

transient

被transient修饰的成员变量在序列化(serialization)时,值会被忽略,在反序列化时会被设为初始值(对象为null)

synchronized

既可以修饰方法也可以修饰方法块,被synchronized修饰的代码块及方法,在同一时间只能被单个线程访问。

  • 实现原理
    对于同步方法,JVM采用ACC_SYNCHRONIZED标记符来实现同步,对于同步代码块采用monitorentermonitorexit两个指令来实现同步。

    方法级的同步是隐式的。同步方法的常量池中会有一个ACC_SYNCHRONIZED标志。当某个线程要访问某个方法的时候,会检查是否有ACC_SYNCHRONIZED,如果有设置,则需要先获得监视器锁,然后开始执行方法,方法执行之后再释放监视器锁。这时如果其他线程来请求执行方法,会因为无法获得监视器锁而被阻断住。值得注意的是,如果在方法执行过程中,发生了异常,并且方法内部并没有处理该异常,那么在异常被抛到方法外面之前监视器锁会被自动释放。
    同步代码块使用monitorentermonitorexit两个指令实现。可以把执行monitorenter指令理解为加锁,执行monitorexit理解为释放锁。 每个对象维护着一个记录着被锁次数的计数器。未被锁定的对象的该计数器为0,当一个线程获得锁(执行monitorenter)后,该计数器自增变为 1 ,当同一个线程再次获得该对象的锁的时候,计数器再次自增。当同一个线程释放锁(执行monitorexit指令)的时候,计数器再自减。当计数器为0的时候。锁将被释放,其他线程便可以获得锁。

  • 可见性
    可见性是指:当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看到修改的值
    synchronized修饰的代码在开始执行时会加锁, 执行完会解锁,为了保证可见性,需要遵循如下规则:对一个变量解锁之前,必须先把此变量同步回主存,这样解锁之后其他线程可以访问修改后的值。

  • 有序性
    有序性即程序执行的顺序按照代码的先后顺序
    由于处理器优化和指令重排等,CPU还可能对代码进行乱序执行,这就存在有序性问题。
    而synchronized是无法禁止指令重排和处理器优化的。也就是说,synchronized无法避免出现有序性问题,但synchronized仍然提供了有序性保证,具体原因如下:
    Java程序具有天然的有序性:如果在本线程内观察,所有操作都是天然有序的。如果在一个线程中观察另一个线程,所有操作都是无序的。
    由于synchronized修饰的代码,同一时间只能被同一线程访问。那么也就是单线程执行的。所以,可以保证其有序性。

volatile

volatile是一个变量修饰符,无法修饰方法和代码块,用于修饰可能被多线程同时访问的变量。

  • 实现原理
    为了提高处理速度,处理器和内存间存在多级缓存,这样就导致了缓存数据不一致的问题。
    但是对于volatile的变量,当对volatile变量进行写操作时,JVM会向处理器发送一条lock前缀的指令,将这个缓存中的变量回写到系统主存中。但就算写回内存,如果其他处理器缓存的值未更新,仍会有不一致的问题,所以在多处理器情况下需要实现缓存一致性协议
    缓存一致性协议:每个处理器通过嗅探总线上出传播的数据来检查自己缓存的值是否已经过期,当处理器发现自己缓存行的对应的内存地址被修改,就会将当前处理器的缓存行设置为无效,当处理器要操作这个数据时会强制从内存中读取数据到缓存中。

  • 可见性
    前文提到每次修改变量都会同步到主内存和其他缓存所以可以保证变量的可见性

  • 有序性
    volatile将禁止指令重排,保证对被volatile修饰的变量的操作会严格按照代码顺序执行

  • 原子性
    volatile是不能保证原子性的,只有以下两个场景可以使用volatile

    1. 运算结果并不依赖变量的当前值,或确保只有单一线程会修改变量的值
    2. 变量不需要与其他状态变量共同参与不变约束
final

final可以修饰变量、方法、类,表示无法修改的

  • 如果修饰变量则表示这是常量
  • 如果修饰方法则表示不能覆盖
  • 如果修饰类则表示不能继承
static

static用于修饰成员变量和方法,也可以修饰代码块

  • 修饰变量表示被类中所有对象共享
  • 修饰方法表示可以直接由类调用无需实例
  • 修饰代码块表示在类装载入内存是执行一次

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

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

相关文章

nacos占位符配置

有的时候,我们的nacos会出现一个配置文件里,有多个配置项对应的值都是一样的,这个时候nacos就可以用到占位符${}进行参数配置。 auth:api1:host: http://aaa.comapi2:host: http://aaa.com可以将共同的参数提取出来统一配置,后期…

线程间的通信

文章目录 线程间的通讯技术就是通过等待和唤醒机制,来实现多个线程协同操作完成某一项任务,例如经典的生产者和消费者案例。等待唤醒机制其实就是让线程进入等待状态或者让线程从等待状态中唤醒,需要用到两种方法,如下&#xff1a…

Java中的内存数据库与缓存技术

Java中的内存数据库与缓存技术 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿! 1. 内存数据库的概念与优势 1.1 什么是内存数据库? 内存数据库是…

python写的工具代码总结

目录 python画图&处理图片python增大图片的大小(比如将几百K的照片增加到几mb)解决python画图无法显示中文的问题python画折线图 & 一张图上三条折线 & 设置折线marker & chatgpt画折线图的提示词python将png格式的图片转换为jpg格式的图…

红蓝对抗下的内网横向移动渗透技术详解

一、利用Windows计划任务横向移动 Windows计划任务是一个非常实用的功能,可以帮助我们自动完成一些重复性的任务。比如,我们可以设定一个计划任务来自动备份文件、更新软件、执行脚本等,本文主要介绍了如何利用Windows计划任务进行横向渗透。 &#xf…

列举操作redis set的命令

Redis中的Redis中的Set是一种无序的Set是一种无序的、不包含重复元素的字符串集合。、不包含重复元素的字符串集合。操作Redis Set的命令非常丰富,下面列举了一些常用的命令: **S操作Redis Set的命令非常丰富,下面列举了一些常用的命令&#…

C#委托事件的实现

1、事件 在C#中事件是一种特殊的委托类型,用于在对象之间提供一种基于观察者模式的通知机制。 1.1、事件的发送方定义了一个委托,委托类型的声明包含了事件的签名,即事件处理器方法的签名。 1.2、事件的订阅者可以通过运算符来注册事件处理器…

Python基础小知识问答系列-过滤列表元素

1. 问题: 如何根据单一条件过滤列表的元素? 如何根据复杂条件过滤列表的元素? 2. 解决方式: 可以使用推导式生成器,进行单一条件的列表元素过滤,尤其是列表内容较多时; 也可以使用filter函数进行列…

快速排序c++java代码实现

快速排序的思想 &#xff08;基于分治法&#xff09;: 每次选一个基准元素x&#xff0c;通过一次遍历将排序表划分为独立的两部分a[l,k-1],a[k1,r]; 其中左边的元素<x,右边的1元素>x,然后递归下去&#xff0c;直到每个块的大小为1 ; c #include<bits/stdc.h> …

Linux Static Keys和jump label机制

文章目录 前言一、asm goto二、API使用2.1 低版本API2.2 高版本API 三、jump label四、源码分析4.1 数据结构4.2 static_key_false4.3 jump_label_init4.4 __jump_label_transform4.5 static_key_slow_inc/dec 五、__jump_table节5.1 内核5.2 内核模块 六、修改内存代码6.1 x86…

24西安电子科技大学数学与统计学院—考研录取情况

24西安电子科技大学—数学与统计学院—考研录取统计 01、数学与统计学院各个方向 02、24数学与统计学院近三年复试分数线对比 数统院24年院线相对于23年院线增加高达30分&#xff0c;确实增长浮动比较高&#xff0c;接近30分的水平&#xff0c;因此大家更需要好好去努力&#x…

GTest和Catch2单元测试学习(附Cmake测试代码库)

kevin_CTest CTest 单元测试学习 Gitee库&#xff1a; https://gitee.com/bigearrabbit/kevin_ctest.git 示例多是从网页文章上摘取的&#xff0c;大部分记录在下面&#xff0c;或者源码内。供学习参考。 CTest 学习Catch2 框架 单个文档的测试架构&#xff0c;使用方便&am…

FastGPT 报错:undefined 该令牌无权使用模型:gpt-3.5-turbo (request id: xxx)

目录 一、FastGPT 报错 二、解决方法 一、FastGPT 报错 进行对话时 FastGPT 报错如下所示。 [Error] 2024-07-01 09:25:23 sse error: undefined 该令牌无权使用模型:gpt-3.5-turbo (request id: xxxxx) {message: 403 该令牌无权使用模型:gpt-3.5-turbo (request id: x…

人机交互中信息之间的距离

在人机交互中&#xff0c;信息之间的距离可以从多个角度来理解和描述&#xff1a; 1、物理距离 &#xff1a;这指的是用户与交互设备&#xff08;例如电脑、手机、智能设备&#xff09;之间的物理空间距离。随着移动设备的普及和技术的发展&#xff0c;用户可以在不同的物理位置…

vue3中svg图标的封装与使用

组件封装&#xff1a; <template><svg :class"svgClass" :style"{ width: size px, height: size px, color: color, verticalAlign:deviationem}" aria-hidden"true"><use :xlink:href"#icon-${name}" /></s…

scss学习总结

摘录更改至 scss: map:merge 和 each $attribute, $value in $variables 研究 Element-plus 源码时&#xff0c;有以下一段代码&#xff1a; // path: element-plus/packages/theme-chalk/src/button.scss include b(button) {include set-component-css-var(button, $butto…

RISC-V的历史与设计理念

指令集是什么&#xff1f; 如果把软件比作螺丝钉&#xff0c;硬件比作螺母&#xff0c;那么指令集架构就是螺丝钉与螺母的蓝图。我们需要根据蓝图设计可以匹配的螺丝钉与螺母。——包云岗老师 RISC-V的起源 以往比较流行的指令集&#xff1a;ARM&#xff0c;MIPS&#xff0c;X…

FreeRTOS的任务间通信

文章目录 4 FreeRTOS任务间通信4.1 队列4.1.1 队列的使用4.1.2 队列的创建&#xff0c;删除&#xff0c;复位4.1.3 队列的发送&#xff0c;接收&#xff0c;查询 4.2 邮箱&#xff08;mailbox&#xff09;4.2.1 任务中读写邮箱4.2.2 中断中读写邮箱 4.3 队列集4.3.1 队列集的创…

【哈希表】【字符串】个人练习-Leetcode-1814. Count Nice Pairs in an Array

题目链接&#xff1a;https://leetcode.cn/problems/count-nice-pairs-in-an-array/description/ 题目大意&#xff1a;给出一个数列nums[]&#xff0c;求nice对 ( i , j ) (i, j) (i,j)对数。nice对满足0 < i < j < nums.length和nums[i] rev(nums[j]) nums[j] r…

Vue打包文件dist放在SpringBoot项目下运行(正确实现全过程)

项目开发中&#xff0c;一般我们都会使用SpringBootVue进行前后端开发。 在部署时&#xff0c;会后端启动一个服务&#xff0c;再启动一个nginx&#xff0c;nginx中配置前端打包文件dist进行项目访问。 实际上&#xff0c;我们也可以把打包好的dist目录放在SpringBoot项目下进…