深入理解Java中的synchronized关键字

目录

前言

一、什么是synchronized

二、synchronized的底层实现

三、synchronized与其他同步机制的比较

四、synchronized的使用方式

1. synchronized的重入

2.synchronized的异常


前言

        Java是一种面向对象的编程语言,以其强大的并发处理能力而闻名。在多线程编程中,保证线程安全是一个重要的问题。本文将详细探讨Java中的一个关键机制——synchronized关键字,帮助你深刻理解其概念、使用方法及其背后的工作原理。

一、什么是synchronized

   synchronized是Java提供的一种内置同步机制,用于解决多线程环境下的并发问题。当多个线程同时访问共享资源时,可能会出现数据不一致的情况。synchronized通过锁(monitor)的方式来确保同一时间只有一个线程可以访问被保护的代码块,从而避免数据的竞争问题。

二、synchronized的底层实现

        Java中synchronized关键字是通过进入和退出Monitor(监视器)对象来实现的。每个对象都有一个隐式的监视器锁。当我们使用synchronized同步方法或同步代码块时,线程必须先获得该锁才能进入同步区域。

        在JVM内部synchronized是通过字节码指令monitorentermonitorexit来实现的。当线程执行到synchronized区域时,它会尝试获取对象的监视器锁。若成功,则进入同步区域;否则,线程会被阻塞,直到获得锁为止。

三、synchronized与其他同步机制的比较

除了synchronized之外,Java还提供了其他一些高级的同步机制,如ReentrantLockSemaphore等。以下是它们的一些比较:

  • 可重入性synchronizedReentrantLock都是可重入锁。可重入性意味着同一个线程可以多次进入同步代码块而不会被自己阻塞。

  • 灵活性ReentrantLocksynchronized更加灵活。它提供了更多的方法,例如lockInterruptibly()tryLock()等,可以更精细地控制锁的行为。

  • 性能:在较早版本的Java中,synchronized的性能表现较差。但从Java 6开始,JVM对synchronized做了诸多优化,如偏向锁、轻量级锁以及自旋锁等,使其性能有了显著提升。

  • 条件变量ReentrantLock提供了Condition类,可以实现多个等待队列,配合await()signal()方法实现更加复杂的线程间通信。而synchronized只能依赖于wait()notify()notifyAll()方法来管理线程间的通信。

四、synchronized的使用方式

        关键字synchronized拥有锁重入的功能,也就是在使用synchronized时,当一个线程得到了一个对象的锁后,再次请求此对象时是可以再次得到该对象的锁。出现异常,锁自动释放。

1. synchronized的重入

package com.ctb.sync5;
/*** synchronized的重入* * @author biao** 2024年*/
public class SyncDubbo1 {
​public synchronized void method1(){System.out.println("method1..");method2();}public synchronized void method2(){System.out.println("method2..");method3();}public synchronized void method3(){System.out.println("method3..");}public static void main(String[] args) {final SyncDubbo1 sd = new SyncDubbo1();Thread t1 = new Thread(new Runnable() {@Overridepublic void run() {sd.method1();}});t1.start();}
}

结果: 

注:synchronized的重入,在同时添加都synchronized锁后,在得到一个对象的锁后是可以再次得到该对象的锁的

package com.ctb.sync5;
/*** synchronized的重入* * @author biao** 2024年*/
public class SyncDubbo2 {
​static class Main {public int i = 10;public synchronized void operationSup(){try {i--;System.out.println("Main print i = " + i);Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}}static class Sub extends Main {public synchronized void operationSub(){try {while(i > 0) {i--;System.out.println("Sub print i = " + i);Thread.sleep(100);      this.operationSup();}} catch (InterruptedException e) {e.printStackTrace();}}}public static void main(String[] args) {Thread t1 = new Thread(new Runnable() {@Overridepublic void run() {Sub sub = new Sub();sub.operationSub();}});t1.start();}}
​

注:也可以通过继承的方式进行synchronized的重入

2.synchronized的异常

        对于web应用程序,异常释放锁的情况,如果不及时处理,很可能对你的应用程序业务逻辑产生严重的错误,比如你现在执行一个队列任务,很多对象都在去等待第一个对象正确执行完毕再去释放锁,但是第一个对象由于异常的出现,导致业务逻辑没有正常执行完毕。所以这一点一定要引起注意,在编写代码的时候,一定要考虑周全。

package com.ctb.sync5;
/*** synchronized的异常* * @author biao** 2024年*/
public class SyncException {
​private int i = 0;public synchronized void operation(){while(true){try {i++;Thread.sleep(200);System.out.println(Thread.currentThread().getName() + " , i = " + i);if(i == 10){Integer.parseInt("a");//throw new RuntimeException();}} catch (Exception e) {//InterruptedExceptione.printStackTrace();System.out.println("log info i = " + i);//throw new RuntimeException();//continue;}}}public static void main(String[] args) {final SyncException se = new SyncException();Thread t1 = new Thread(new Runnable() {@Overridepublic void run() {se.operation();}},"t1");t1.start();}}

结果: 

注:在我们运行数据时,当它某条数据出现错误时,继续往下执行,并记录异常数据,后续根据日志去解决问题。

当然我们也可以在异常产生时进行停止数据的变动,

第一种:抛出运行时异常

public synchronized void operation(){while(true){try {i++;Thread.sleep(200);System.out.println(Thread.currentThread().getName() + " , i = " + i);if(i == 10){Integer.parseInt("a");
//                  throw new RuntimeException();}} catch (Exception e) {//InterruptedExceptione.printStackTrace();System.out.println("log info i = " + i);throw new RuntimeException();
//              continue;}}}

结果: 

        第二种:InterruptedException 是 Java 中的一个受检查异常,表示一个线程被中断。当一个线程调用 Thread 类的 interrupt() 方法时,会给该线程设置一个中断标记,表示该线程被中断了。

public synchronized void operation(){while(true){try {i++;Thread.sleep(200);System.out.println(Thread.currentThread().getName() + " , i = " + i);if(i == 10){Integer.parseInt("a");
//                  throw new RuntimeException();}} catch (InterruptedException e) {//InterruptedExceptione.printStackTrace();System.out.println("log info i = " + i);
//              throw new RuntimeException();
//              continue;}}}

结果: 

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

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

相关文章

LLM 理论知识

LLM 理论知识 一.大型语言模型LLM1.1 大型语言模型 LLM 的概念1.2 常见的 LLM 模型1.2.1 闭源 LLM (未公开源代码)1.2.1.1 GPT 系列1.2.1.1.1 ChatGPT1.2.1.1.2 GPT-4 1.2.1.2 Claude 系列1.2.1.1.3 PaLM/Gemini 系列1.2.1.1.4 文心一言1.2.1.1.5 星火大模型 1.2.2. 开源 LLM1.…

threejs材质的贴图(四)

效果 代码实现 import ./style.css import * as THREE from three import { OrbitControls } from three/examples/jsm/controls/OrbitControls.js//相机轨道控制器 import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader.js"//加载hdr文件作为环境贴…

排序模型的奥秘:如何用AI大模型提升电商、广告和用户增长的效果

摘要 排序模型是数字化营销中最重要的工具之一,它可以帮助我们在海量的信息中筛选出最符合用户需求和偏好的内容,从而提高用户的满意度和转化率。本文从产品经理的视角,介绍了常见的排序模型的原理和应用,包括基于规则的排序、基…

【ROS1转ROS2示例】

ROS1中的代码: 这是一个循环函数: ros::Rate loop_rate(10); // Adjust the publishing rate as neededwhile (ros::ok()){loop_rate.sleep();} 如果转ROS2,可以使用rclcpp::WallRate或者直接依赖于执行器(Executor)的循环来实现类似的功…

如何有效处理独立站遭受的网络攻击

随着电子商务的蓬勃发展,独立站成为了众多商家展示产品、吸引客户的重要平台。然而,这同时也吸引了不法分子的目光,使得独立站成为网络攻击的重灾区。本文将深入探讨独立站可能遭受的各种网络攻击类型,并提供一系列实用且可运行的…

Flutter第十一弹:Scaffold(脚手架)

目标: 1.什么是脚手架? 2.脚手架什么时候使用? 一、Scaffold属性 Scaffold通常配合MaterialApp使用。 1.1 MaterialApp是什么? MaterialApp是Flutter中的一个重要小部件,它作为应用程序的根部小部件,并…

【C语言初阶】分支语句

🌟博主主页:我是一只海绵派大星 📚专栏分类:C语言 ❤️感谢大家点赞👍收藏⭐评论✍️ 目录 一、什么是语句 二、if语句 悬空else 三、switch语句 default 四、switch语句与if-else语句性能对比如何&#xff1f…

分布式技术导论 — 探索分析从起源到现今的巅峰之旅(消息队列)

探索分析从起源到现今的巅峰之旅 分布式队列 - Kafka架构特性可扩展性磁盘优化与顺序访问大容量存储与历史数据利用高效数据封装与压缩智能内存管理与OS缓存利用 Kafka发布/订阅模型Kafka架构分析Producer和Consumer接口交互Producer通过Topic发送数据Consumer通过Topic消费数据…

MD5 对字符串加密和获取文件MD5值的实现

一.MD5对字符串加密 我们使用openssl库对字符串进行MD5加密 #include <openssl/md5.h> #include <openssl/evp.h>std::string calculate_md5(const std::string &input) {unsigned char digest[MD5_DIGEST_LENGTH];std::string md5;EVP_MD_CTX *mdContext =…

springboot项目mapper无法自动装配,未找到 ‘userMapper‘ 类型的Bean解决办法.

一开始我看到了这个回答&#xff1a;springboot项目mapper无法自动装配&#xff0c;未找到 ‘userMapper‘ 类型的 Bean解决办法&#xff08;含报错原因&#xff09;_无法自动装配。找不到 usermapper 类型的 bean。-CSDN博客 mapper无法自动装配&#xff0c;未找到 ‘userMap…

MyBatis系列四: 动态SQL

动态SQL语句-更复杂的查询业务需求 官方文档基本介绍案例演示if标签应用实例where标签应用实例choose/when/otherwise应用实例foreach标签应用实例trim标签应用实例[使用较少]set标签应用实例[重点]课后练习 上一讲, 我们学习的是 MyBatis系列三: 原生的API与配置文件详解 现在…

算力、存力、智算中心-2024北京AI算力产业峰会

2024北京AI算力产业峰会 时间&#xff1a;2024年9⽉25-27⽇ 地点&#xff1a;北京国家会议中⼼ 活动隶属&#xff1a;中国国际信息通信展览会 主办单位&#xff1a;工业和信息化部 执⾏单位&#xff1a;中国计算机⾏业协会信息存储与安全专委会 深圳热点资讯展览有限公司 …

自定义Unity组件——ABManager(AB包管理器)

需求描述 在Unity3D引擎中&#xff0c;AB包作为常用的游戏资源存储格式之一。而对于资源管理我们就不得不谈到集中管理的优势了&#xff0c;通过统一的接口加载和卸载AB包及其中的资源将进一步提升我们的编程效率。本文将围绕这个需求进行尝试。 功能描述 1. AB包的加载包括同…

【C#上位机应用开发实战】—机器视觉检测

#机器视觉 在现代工业生产中&#xff0c;机器视觉检测技术扮演着越来越重要的角色。它通过计算机视觉技术来实现对工件的自动化检测和判断&#xff0c;大大提高了生产效率和产品质量。而在机器视觉检测的应用中&#xff0c;C#作为一种简洁易用且功能强大的编程语言&#xff0c…

报表开发工具DevExpress Reporting v23.2 - 增强PDF导出、多平台打印等

DevExpress Reporting是.NET Framework下功能完善的报表平台&#xff0c;它附带了易于使用的Visual Studio报表设计器和丰富的报表控件集&#xff0c;包括数据透视表、图表&#xff0c;因此您可以构建无与伦比、信息清晰的报表。 DevExpress Reporting控件日前正式发布了v23.2…

ClickHouse安装与下载22.3.2.2

ClickHouse安装与下载 目录 1. ClickHouse简介 1.1 ClickHouse优点&#xff1a; 1.2 ClickHouse缺点&#xff1a; 1.3 ClickHouse引擎&#xff1a; 1.3.1 数据库引擎 1.3.2 表引擎 2. ClickHouse下载安装 2.1 ClickHouse下载安装 2.2 ClickHouse使用 1. ClickHouse简…

中国剩余定理——AcWing 204. 表达整数的奇怪方式

中国剩余定理 定义 中国剩余定理最早出自我国古代的《孙子算经》&#xff0c;是数论中的一个重要定理。它描述了这样一种情况&#xff1a;在模运算下&#xff0c;对于一组线性同余方程组&#xff0c;存在唯一解的条件和求解方法。 运用情况 常用于在一些涉及到按不同模的余…

实习日记(一)

实习日记&#xff08;一&#xff09; 前话 来快手实习有一段时间了&#xff0c;博客也有一段时间没有更了&#xff0c;最近一段时间的状态是白天忙着工作晚上忙着实验室的科研&#xff0c;虽然很累但收获很多&#xff0c;让我了解到工作和科研确实是两个不同的方向&#xff0…

实际项目中如何实现分库分表

数据库分库分表 数据库分库分表是一种数据库设计和架构优化策略&#xff0c;目的是为了应对大规模数据和高并发访问带来的挑战。它将单个大型数据库分解为多个较小的、更易于管理的部分&#xff0c;即“库”&#xff08;也称为数据仓库或实例&#xff09;&#xff0c;并根据某…

安全宣传咨询日活动向媒体投稿记住这个投稿好方法

在信息爆炸的时代,作为单位的信息宣传员,我肩负着将每一次重要活动,特别是像“安全宣传咨询日”这样的公益活动,有效传达给公众的重任。这份工作看似简单,实则充满了挑战,尤其是在我初涉此领域时,那段曲折而又难忘的投稿经历,至今记忆犹新。 初探投稿之海,遭遇重重困难 起初,我…