Java实现线程同步的几种方式

synchronized

特点:

  • 简单易用: synchronized 关键字的使用非常简单,它可以直接应用于方法或代码块上。对于对象和类的同步方法,JVM负责加锁和释放锁,开发者不需要手动操作。
  • 自动释放锁: 当synchronized方法或代码块执行完毕后,锁会自动释放,减少了死锁发生的可能性。

实现原理:

  • synchronized 是基于JVM层面实现的同步机制。当一个线程进入synchronized标记的方法或代码块时,它会自动获得锁,并在退出时自动释放锁。
  • 锁的持有对象根据synchronized修饰的是静态方法、实例方法还是代码块,分别是类的Class对象、实例对象或者指定的对象。
  • 在JVM实现中,synchronized用的锁机制是依赖于每个对象内部的一个监视器锁(Monitor)。进入synchronized块的线程必须获取到这个监视器锁。

ReentrantLock

特点:

  • 可中断的锁获取操作: ReentrantLock 提供了一种能够中断等待锁的线程的机制,这可以避免死锁。
  • 可实现公平锁: 可以通过构造函数指定ReentrantLock为公平锁,这意味着等待时间最长的线程会首先获得锁。
  • 锁绑定多个条件(Condition): ReentrantLock 提供了一种能够绑定多个条件(Condition)的机制,这可以分别通知等待中的线程,实现更细粒度的线程同步。

实现原理:

  • ReentrantLock 是基于Java代码层面实现的,属于java.util.concurrent.locks包的一部分。它提供了比synchronized更丰富的操作,能够更精细地控制锁的获取和释放。
  • ReentrantLock 实现了Lock接口,它提供了lock()unlock()tryLock()lockInterruptibly()等方法来控制锁的获取和释放。
  • 锁的公平性由构造函数传入的布尔值决定,通过内部的同步队列(AQS - AbstractQueuedSynchronizer)来管理锁的获取和释放。
  • 条件变量(Condition)的实现提供了类似Object监视器方法(wait()notify()notifyAll())的功能,但它们更加灵活,可以与任意Lock实现配合使用。

让我们更详细地探讨Java中的几种线程同步机制,并通过实际场景来举例说明它们的应用。

volatile关键字和Atomic类都是Java并发编程中保证共享变量操作安全的机制,但它们各有特点和适用场景。

volatile关键字

特点:

  • 简单易用: 直接将变量声明为volatile,无需通过特定的方法访问变量,使得代码更简洁、易读。
  • 保证可见性: 确保一个线程修改了变量的值后,其他线程立即可见这个修改。
  • 避免指令重排序:volatile变量的读写操作前后,不会进行指令重排优化,这在某些情况下是非常重要的。

实现原理:

  • volatile变量的读写操作直接作用于主内存,而普通变量则可能仅作用于CPU缓存中。
  • 当一个变量被声明为volatile之后,线程在读取该变量时会从主内存刷新最新的值,而在写入时会将变量的值刷新回主内存,并且写操作会导致其他线程中的缓存无效。

Atomic类

特点:

  • 支持原子性操作: 提供了一系列原子操作API,如自增(incrementAndGet)、自减(decrementAndGet)、设置新值(set)等,不仅保证可见性,也保证了操作的原子性。
  • 广泛的操作支持: 对于复杂的原子性操作提供了支持,比如带有条件的更新。
  • 性能: 相对于锁(如synchronized)来说,Atomic类在高并发场景下通常能提供更好的性能。

实现原理:

  • Atomic类通过底层硬件的CAS(Compare-And-Swap)操作实现原子性更新,这是一种无锁的同步机制。
  • CAS操作包括三个操作数——内存位置(V)、预期原值(A)和新值(B)。如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值。否则,不做任何操作。整个过程是原子的。

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

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

相关文章

基于Java+SpringBoot+Vue幼儿园管理系统(源码+文档+部署+讲解)

一.系统概述 随着信息时代的来临,过去的传统管理方式缺点逐渐暴露,对过去的传统管理方式的缺点进行分析,采取计算机方式构建幼儿园管理系统。本文通过课题背景、课题目的及意义相关技术,提出了一种教 学生信息、学生考勤、健康记录…

Python map遍历

在Python中,map 函数是一个内置函数,它将指定的函数应用于给定序列(如列表、元组等)的每个项,并返回一个迭代器,该迭代器包含所有项经过指定函数处理后的结果。 ### map 函数的基本用法 map 函数的语法如…

centos如何卸载mysql

在CentOS系统中卸载MySQL,你可以遵循以下步骤: 停止MySQL服务: 1sudo systemctl stop mysqld 列出已安装的MySQL相关组件: 1sudo yum list installed | grep mysql 卸载所有MySQL相关的RPM包: 1sudo yum remove mysq…

PM2+Linux部署nuxt.js

PM2Linux部署nuxt.js 开始我使用了docker部署我的springboot项目,链接在这里,因为我是前后端分离项目,前端使用的nuxt.js框架,所以需要另外部署一下项目,以下是部署流程 1.将本地的nuxt项目打包 npm run build #生成…

Fecify 商品标签功能

关于商品标签 商品标签是指商家可以在展示商品时,自己创建一个自定义标签,可自定义某个关键词或短语。这样顾客在浏览商城时,只需要通过标签就能看到更直观的展示信息。 商品标签可以按照用户的属性、行为、偏好等进行分类,标签要…

传输大咖22|如何利用ProtoBuf实现高效的数据传输?

在今日信息技术日新月异的时代,数据传输的速度与安全性无疑成为了软件开发中的重中之重。无论是微服务架构下的服务间交流,还是客户端与服务器间的数据互动,寻求一种既高效又稳妥的数据传输方式已成为共识。尽管传统的数据格式,如…

坚持10天做完Python入门编程100题第二天

坚持十天做完Python入门编程100题第二天 第8题 列表的排序第9题 字典的创建第10题第11题 对字典的值求和第12题 字典推导式第13题 打印小写字母a~z第14题 计算1-100之间的偶数之和 第8题 列表的排序 列表num_list [3, 1, 5, 9, 15, 2, 7],如和将列表按照从大到小的…

水务行业如何实现数字化转型实现智能化管理

水务行业在当下已经迈入了新的发展阶段,行业内增大了信息化、数字化的探索,尤其是智能化技术出现以后,智能水务概念的提出使得水务数字化转型成为可能。但我国水务行业经历了漫长的发展时期,在很长一段时间内因为存在发展思路、技…

骨传导耳机怎么选?这五款骨传导耳机性能好、配置高,跟着买不出错!

如今,骨传导耳机作为一种创意十足的蓝牙耳机,正在逐渐走入千家万户,成为最受欢迎的耳机款式。然而,随着骨传导耳机的热度增加,市面上开始出现各式各样的骨传导耳机品牌,面对琳琅满目的骨传导耳机品牌&#…

ECharts介绍

ECharts,全称Enterprise Charts,是一款基于JavaScript的数据可视化图表库。它以直观、生动、可交互以及可个性化定制的特点,为数据可视化提供了强有力的工具。ECharts最初由百度团队开源,后于2018年初捐赠给Apache基金会&#xff…

基于SpringBoot的“垃圾分类网站”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“垃圾分类网站”的设计与实现(源码数据库文档PPT) 开发语言:Java 数据库:MySQL 技术:SpringBoot 工具:IDEA/Ecilpse、Navicat、Maven 系统展示 系统功能结构图 系统功能界面图 用户登录、用户注…

方案分享 | 针对ETC系统的OBE-SAM模块设计方案

ETC(Electrical Toll Collection)不停车收费是目前世界上最先进的路桥收费方式。通过安装在车辆挡风玻璃上的车载单元与安装在收费站 ETC 车道上的路侧单元之间的微波专用短程通讯,利用计算机联网技术与银行进行后台结算处理,从而…

2024软件测试工具测评,总有一款适合你!

在软件开发周期中,测试是确保产品质量的关键环节。随着企业对于软件质量的要求日益提升,测试人员面临着前所未有的挑战,“工欲善其事必先利其器”,选择一款高效、实用的软件测试工具,不仅能够提升测试效率,…

Unity发布webgl之后打开streamingAssets中的html文件

Unity发布webgl之后打开streamingAssets中的html文件 路径的拼接 /// <summary>/// 从配置文件中获取上位机的URL/// </summary>private void GetURLAboutUpLink(){Uri upLinkConfig new System.Uri(Path.Combine(Application.streamingAssetsPath "/UPLin…

ElasticSearch分词检索

1. 倒排索引&#xff1a;表示一种数据结构&#xff0c;分词词条与文档id集合的隐射关系 2. 它跟关系型数据库是一种互补的关系&#xff0c;因为关系型数据库支持事务操作&#xff0c;满足ACID原则 3. 索引库的文档字段只允许新增不允许修改 1.创建索引库 put /索引库名称2.1 …

【Leetcode 1793】好子数组的最大分数 —— 单调栈

1793. 好子数组的最大分数 给你一个整数数组nums&#xff08;下标从0开始&#xff09;和一个整数k。 一个子数组(i, j)的 分数 定义为min(nums[i], nums[i1], ..., nums[j]) * (j - i 1)。一个 好 子数组的两个端点下标需要满足i < k < j。 请你返回 好 子数组的最大…

吴恩达2022机器学习专项课程(一) 5.8 学习率的选择

问题预览/关键词 梯度下降不正常工作的曲线是什么样子&#xff1f;如何调试学习率来检测代码中的bug&#xff1f;学习率过小的后果是&#xff1f;如何选择学习率&#xff1f; 笔记 1.曲线错误的样子 曲线没有逐步递减&#xff0c;由于学习率选择过大或代码有bug。 2.调试…

LeetCode-279. 完全平方数【广度优先搜索 数学 动态规划】

LeetCode-279. 完全平方数【广度优先搜索 数学 动态规划】 题目描述&#xff1a;解题思路一&#xff1a;Python 动态规划五部曲&#xff08;完全平方数就是物品&#xff08;可以无限件使用&#xff09;&#xff0c;凑个正整数n就是背包&#xff0c;问凑满这个背包最少有多少物品…

在react项目中使用react-router-dom

如何在react项目中使用react-router-dom 使用 npx create-react-app b初始化项目,npm i react-router-dom安装router依赖首先从react-router-dom包中导出createBrowserRouter对象来创建路由对象和router.js文件 // 创建router文件 import { createBrowserRouter } from "…

MySQL面试题系列-12

MySQL是一个关系型数据库管理系统&#xff0c;由瑞典 MySQL AB 公司开发&#xff0c;属于 Oracle 旗下产品。MySQL是最流行的关系型数据库管理系统之一&#xff0c;在 WEB 应用方面&#xff0c;MySQL是最好的RDBMS (Relational Database Management System&#xff0c;关系数据…