Synchronized相关问题

1、synchronized 为什么是非公平锁?非公平体现在哪些地方?

1)当持有锁的线程释放锁时,先将monitor锁对象的持有者 owner 属性赋值为 null,唤醒EntryList等待链表中的一个线程,但是线程尝试获取锁失败时,进入阻塞队列等待的先后顺序,和被唤醒、获取锁的顺序是不一致的,也就是说你先进入阻塞队列等待,当持有锁的线程释放锁时,不代表你就会先获取锁。

2)当持有锁的线程释放锁时,如果有其他线程刚好在尝试获取锁(例如自旋),则可以马上获取到锁。

2、什么是公平锁

        公平锁:公平锁是指,当锁被其他线程持有后,剩下的线程尝试获取锁失败,会按照先后顺序进入阻塞队列/等待链表中排队、等待,当持有锁的线程释放锁时,阻塞队列中排在前面的线程会优先被唤醒、获取锁,这就称为公平锁。在Java中JUC包下的AQS就可以实现公平锁


        非公平锁:由上面结论我们举反例可以知道,非公平锁就是,我不管你是否先来,谁先抢到锁谁就执行,sychronized就是一个非公平锁。
        但为什么呢?其实很简单,在sychronized中有两个池的概念,一个是EntryList,一个是WaitSet,EntryList是一个单链表结构,当线程获取锁失败后,线程就会被封装称Entry对象然后加入到EntryList中。当某个持有锁线程调用wait()方法,线程就会释放锁然后加入到WaitSet中,当该线程被唤醒后会加入到EntryList中等待JVM调用。

        但JVM并不会按照顺序去调用EntryList中的线程,而是随机调用,这也就导致了sychronized是一个非公平锁。

3、线程安全本质是什么,Java 如何保证线程安全? 

        答:线程安全是指在多线程环境中,多个线程对共享数据的访问和修改不会产生不一致或者不正确的结果。Java提供了多种机制来保证线程安全,其本质是通过控制并发访问共享资源的方式来实现的。

        Java的线程安全是建立在原子性、可见性和有序性这三个基本特点上的。

  •         原子性指的是一个操作不会被中断,要么全部完成,要么全部不完成;
  •         可见性指的是多个线程访问同一个共享变量时,一个线程修改了变量,其他线程都可以立刻看到这个修改的结果;
  •         有序性指的是程序的执行顺序按照代码的先后顺序执行。

Java提供了以下多种机制来保证线程安全:

  •         synchronized关键字:通过互斥锁来保证同一时刻只有一个线程获得锁,访问共享资源,其他线程需要进入阻塞队列,变成阻塞状态,等待锁的释放。synchronized关键字可以修饰方法、代码块或者静态方法。
  •         ReentrantLock类:ReentrantLock是可重入锁,与synchronized关键字相似。它提供了更多的灵活性和语义选择。线程获取锁时可以选择不同的等待策略,例如公平锁和非公平锁。
  •         volatile关键字:volatile关键字可以保证线程可以立即看到共享变量的更改,而不会看到变量的过期值。volatile关键字适用于单纯的读取数据的操作,不能保证多个操作之间的原子性。
  •         AtomicInteger类:AtomicInteger是一个原子类,提供了多个原子性方法,如getAndIncrement()、getAndDecrement()、getAndAdd()等。这些方法是原子性的,不需要使用synchronized关键字来保证线程安全。

        通过使用以上这些机制,Java可以有效地保证线程安全。在开发多线程程序时,需要注意数据的访问和修改顺序,避免不正确的并发操作。同时,还应该避免死锁和饥饿等并发问题,以提高程序的性能和健壮性。

4、可重入锁

        可重入锁 :字面意思是“可以重新进入的锁”,可重入锁指的是允许同一个线程多次获取同一把锁。比如一个线程在执行一个带锁的方法,该方法中又调用了另一个需要相同锁的方法,则该线程可以直接执行调用的方法,而无需重新获得锁;

        再比如一个线程调用递归函数,递归函数里有加锁的操作,在递归过程中这个锁不会阻塞自己,这个锁就是可重入锁(因为这个原因可重入锁也叫做递归锁)。

        可重入锁可以避免死锁的出现:自己把自己阻塞住了、锁住了

        synchronized锁和ReentrantLock锁都是可重入锁,两者都是同一个线程每进入一次,锁的计数器都自增1,所以要等到锁的计数器下降为0时才能释放锁。

 线程在获取锁的时候,实际上就是获得一个监视器对象(monitor)

 线程试图获取锁也就是获取monitor(monitor对象存在于每个Java对象的对象头中,synchronized 锁便是通过这种方式获取锁的,也是为什么Java中任意对象可以作为锁的原因) 

在JDK1.6之后 synchronized锁引入了锁升级的过程 无锁、偏向锁、轻量级锁、重量级锁,4种状态,4种状态会随着竞争的情况逐渐升级,升级的过程是不可逆的

在没有竞争时,synchronized 做了很多优化,如偏向锁、轻量级锁

注意: 加在成员方法上的synchronized关键字相当于 synchronized(this) 锁住的this对象;
加在静态方法上的synchronized关键字相当于synchronized(类.clss)锁住的当前类对象


 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【病毒分析】phobos家族2700变种加密器分析报告

1.样本信息 ⽂件名Fast.exeSHA2563c95bd8e14f6aa92e94ec3318d23a8cc34192259MD528c6c0b4f54912ec73c9bfeb3f2a8f07运行平台Windows 2.感染迹象 2.1 文件结构分析 整体文件大小为200k,把冗余数据去掉,发现仍然可以运行,大小变为56k。与phobos家族的标准一致。 2.1.1 勒索信 …

python笔记 | 哥德巴赫猜想

哥德巴赫猜想:每个不小于6的偶数都可以表示成两个素数之和。 素数:只能被1和自身整除的正整数。就是大于1且除了1和它本身之外没有其他因数的数。例如,2、3、5、7、11等都是素数,而4、6、8、9等则不是素数。 下面这段Python代码…

Day 16 Linux服务管理和日志管理

服务管理 启动服务:systemctl start 服务名 停止服务:systemctl stop 服务名 重启服务:systemctl restart 服务名 重新加载配置文件:systemctl reload 服务名(期间并不停止服务进程) 查看服务运行状态…

十、OOP面向对象程序设计(五)

1、什么是接口以及接口的运用 1)接口定义 Java接口(Interface),是一些列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能。) 2)接口定义的一般形式 修饰符:…

git使用(上传自己的项目到github上)

之前最早使用的方式是使用as上面的菜单功能VCS——>share project on github,,, 现在我们使用命令的方法上传。 第一步:在github上面Create a new repository 这里输入仓库的名称和描述,勾选Add a README file,这会在创建仓库的时候添加…

一些重新开始面试之后的八股文汇总

一、内存中各项名词说明 1、机器内存概念说明 linux中的free命令可以查看机器的内存使用情况,vmstat命令也可以 其中不容易被理解的是: 内存缓冲/存数(buffer/cached) 1.buffers和cache也是RAM划分出来的一部分地址空间 2.buff…

css div添加滚动条(附加源码)

问题描述 先看效果图。 每个商品通过后台接口查询出来,前端v-for进行显示,所以这块我要添加一个滚动条,我不确定有多少个商品。 解决方案 实现思路:div设置高度为1000rpx(我这边是举例,根据实际场景去设…

Jenkins 流水线多阶段构建

Jenkins流水线配置遇到 无法识别的。需要使用 自定义环境 项。 比如官网的在流水线中使用Docker Started by remote host 172.17.0.1 Obtained Jenkinsfile from git http://10.99.20.51:8082/root/java-devops-demo.git org.codehaus.groovy.control.MultipleCompilationErro…

Ribbon 添加右侧区域菜单项

效果图如下所示: 类似与上图效果所示,代码如下: RibbonPage* pageHome1 ribbonBar()->addPage(tr("Home")); //实现代码: { QMenu* menuOptions ribbonBar()->addMenu(tr("Options"))…

节点加密技术:保障数据传输安全的新利器

随着信息技术的快速发展,网络数据的安全传输问题日益凸显。节点加密技术作为一种新兴的加密手段,正逐渐成为保障数据传输安全的重要工具。本文将探讨节点加密技术的原理、应用及其优势,并分析其未来的发展趋势。 节点加密技术的原理 节点加密…

腾讯InstantMesh30秒图片生成3D模型;微软实时生成会说话的头像VASA;由 AI 创作的恶搞视频片段Sitcom Simulator

✨ 1: InstantMesh 30 秒内从一张图片生成 3D 模型 InstantMesh是一个基于单张图片,利用先进的稀疏视图大型重建模型(LRM)架构,快速生成3D网格(Mesh)的工具。这个框架允许用户将2D图片转换成3D模型&#…

学习笔记------时序约束之时钟周期约束

本文摘自《VIVADO从此开始》高亚军 主时钟周期约束 主时钟,即从FPGA的全局时钟引脚进入的时钟或者由高速收发器输出的时钟。 对于时钟约束,有三个要素描述:时钟源,占空比和时钟周期。 单端时钟输入 这里我们新建一个工程&#x…

如何使用Flask搭建web程序框架并实现无公网IP远程访问本地程序

文章目录 前言1. 安装部署Flask并制作SayHello问答界面2. 安装Cpolar内网穿透3. 配置Flask的问答界面公网访问地址4. 公网远程访问Flask的问答界面 前言 Flask是一个Python编写的Web微框架,让我们可以使用Python语言快速实现一个网站或Web服务,本期教程…

HarmonyOS NEXT 使用XComponent + Vsync 实现自定义动画

介绍 XComponent 提供了应用在 native 侧调用 OpenGLES 图形接口的能力,本文主要介绍如何配合 Vsync 事件,完成自定义动画。在这种实现方式下,自定义动画的绘制不在 UI 主线程中完成,即使主线程卡顿,动画效果也不会受…

汽车充电桩充电效率的四大决定因素

随着电动汽车的快速普及,交流充电桩作为电动汽车的充电基础设施,其充电效率受到了广泛的关注。接下来,我们将深入探讨交流充电桩的充电效率,包括充电效率的定义、影响因素以及提升方法。 充电效率的定义 交流充电桩的充电效率指的…

基于Springboot+Vue的Java项目-网上超市系统开发实战(附演示视频+源码+LW)

大家好!我是程序员一帆,感谢您阅读本文,欢迎一键三连哦。 💞当前专栏:Java毕业设计 精彩专栏推荐👇🏻👇🏻👇🏻 🎀 Python毕业设计 &am…

构建现代网页的引擎:WebKit架构揭秘

在网络信息迅猛增长的今天,浏览器已经成为我们接触世界的重要窗口。而在浏览器的核心,有一个强大的引擎在默默地支撑着网页的渲染和执行,这就是WebKit。 WebKit的核心组件 WebKit作为开源浏览器引擎,由苹果公司发展而来&#x…

前端编程环境配置

目录 vscode插件的安装快捷键常用的快捷键自定义快捷键 vscode 插件的安装 汉化,将vscode改为中文版 Chinese (Simplified)修改开始标签,结束标签跟着一起变化 Auto Rename Tag颜色主题 One Dark Pro格式化代码(建议使用系统自带) 配置&#xff1a…

二叉树和数据结构

小红的完全二叉树构造 题目描述 小红想构造一个总共 n 个节点完全二叉树,该二叉树满足以下两个性质: 1. 所有节点的权值值为 1 ~ n 的一个排列。 2. 除了根节点以外,每个节点的权值和它父亲的权值的乘积为偶数。 请你帮小红构造出这个二叉树…

Docker容器逃逸-特权模式-危险挂载-Procfs

Docker容器逃逸-特权模式-危险挂载(95天) Docker这个概念: Docker 容器与虚拟机类似,但二者在原理上不同,容器是将操作系统层虚拟化,虚拟机则是虚拟化硬件,因此容器更具有便携性、高效地利用服务…
最新文章