我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Java 关键字:synchronized详解

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Java 关键字:synchronized详解

synchronized详解

基本使用

在这里插入图片描述

Java中的synchronized关键字用于在多线程环境下确保数据同步。它可以用来修饰方法和代码块
当一个线程访问一个对象的synchronized方法或代码块时,其他线程将无法访问该对象的其他synchronized方法或代码块。这样可以确保在同一时间只有一个线程能够执行该代码块或方法,避免了多线程环境下的数据不一致问题,例如:

public class SynchronizedExample {    private int count = 0;    public synchronized void increment() {        count++;    }}

在上面的代码中,increment()方法是一个synchronized方法。当多个线程访问这个方法时,只有一个线程能够执行该方法的代码,其他线程将被阻塞。
synchronized关键字也可以用来修饰代码块,如:

public void increment() {    synchronized(this) {        count++;    }}

在上面的代码中,synchronized关键字修饰的是一个代码块,并且锁对象是当前对象(this)
注意:synchronized关键字会导致线程上下文切换和资源竞争,所以在使用时要注意性能问题

源码解析

底层实现是通过 Java 虚拟机(JVM)的对象头和监视器锁机制实现的

具体来说,当一个线程访问一个对象的 synchronized 方法或代码块时,它会试图获取该对象的监视器锁。如果该锁未被其他线程占用,该线程将获得该锁并执行代码;如果该锁被其他线程占用,该线程将进入阻塞状态,等待获取该锁

synchronized 是Java中用于实现同步的关键字,它在底层通过监视器锁(Monitor)来实现。下面是synchronized的源码解析:

在Java中,每个对象都有一个与之关联的监视器锁,也称为内置锁或对象锁。当线程进入一个synchronized方法或代码块时,它会尝试获取该对象的监视器锁。如果锁没有被其他线程占用,则该线程获得锁并开始执行代码;如果锁已经被其他线程占用,则该线程将被阻塞,直到锁被释放。

在Java虚拟机中,每个对象头中都包含一部分用于实现synchronized的相关信息。这些信息包括:

  • mark word:用于存储对象的标记信息,包括锁的状态。
  • Klass pointer:指向对象的类元数据,包括synchronized的相关信息。
  • monitor:与对象关联的监视器,它记录了当前占用锁的线程、等待锁的线程队列等。

当一个线程尝试获取一个对象的锁时,虚拟机会检查对象头中的标记信息。如果对象的锁状态为无锁状态,即未被其他线程占用,则该线程可以获取锁,并将标记信息设置为锁定状态。如果对象的锁状态为已锁定,并且当前线程是锁的所有者,则该线程可以继续执行代码。如果对象的锁状态为已锁定,并且当前线程不是锁的所有者,则该线程将被放入等待队列中,进入阻塞状态。

当持有锁的线程执行完synchronized方法或代码块后,它会释放锁,即将对象头中的锁状态置为无锁状态,并唤醒等待队列中的一个线程,使其获取锁并继续执行。

需要注意的是,synchronized关键字可以修饰方法和代码块。在方法上修饰的synchronized表示对整个方法进行同步,而在代码块上修饰的synchronized表示对该代码块进行同步,使用的锁对象通常是方法所属对象或指定的对象。

总结起来,通过监视器锁的机制,Java的synchronized能够保证同一时刻只有一个线程访问同步代码块或方法,避免了多线程的数据竞争和并发问题。

这里给出一份简化的 synchronized 关键字的源码:

public void synchronized method() {    // 加锁    Monitor.enter(this);    try {        // 同步代码块    } finally {        // 释放锁        Monitor.exit(this);    }}

在这份代码中,方法通过调用 Monitor.enter 方法获取当前对象的监视器锁,并在 finally 块中调用 Monitor.exit 方法释放该锁。因此,在 synchronized 方法内部的代码可以保证在任意时刻只有一个线程可以访问

常见面试题

  • synchronized 方法和 synchronized 块的区别是什么?
    作用范围:synchronized 方法将整个方法体作为同步区块,而 synchronized 块可以将任意代码块作为同步区块
    锁的对象:synchronized 方法锁定的是整个对象,而 synchronized 块锁定的是在括号内指定的对象
    可控性:synchronized 方法的同步粒度比较大,不够灵活;而 synchronized 块可以更灵活地控制同步代码块的大小
    综上所述,在确定同步粒度时,通常使用 synchronized 块比使用 synchronized 方法更灵活,但是如果整个方法都需要同步,使用 synchronized 方法会更加简单易懂
  • 什么情况下可以使用 synchronized 关键字?
    synchronized 关键字可以用于在多线程环境下保证方法或代码块的原子性。具体来说,如果一个线程正在执行同步方法或代码块,则其他线程将无法访问该方法或代码块
    常见情况包括:
    当多个线程访问共享资源时,可以使用 synchronized 关键字保证线程的安全
    在访问共享变量时,需要对其进行同步控制
  • 在线程通信中,可以使用 synchronized 关键字保证线程之间的同步通信
    synchronized 关键字的性能开销如何?
    synchronized 关键字的使用会带来一些性能开销,因为它需要在多个线程之间进行同步。当线程访问同步代码块时,它必须获得锁,这会增加额外的开销。如果同步代码块执行时间过长,其他线程将一直等待,进而降低程序的性能。
    因此,应该尽量避免在高并发情况下使用 synchronized,或者使用其他的并发控制机制,如 java.util.concurrent 包中的锁和原子操作类等。
  • synchronized 关键字如何实现可重入?
    “可重入” 指的是同一线程可以多次获取同一个锁。例如,当线程 A 进入一个同步块时,如果它再次试图进入该块,则可以再次获取锁,而不会发生死锁
    在 Java 中,synchronized 关键字可以实现可重入,原因如下:
    synchronized 关键字使用对象监视器锁来实现同步。
    对象监视器锁是基于线程的,并且每个线程有一个独立的计数器,用于跟踪它在当前对象上获取的锁的数量。
    当线程试图获取锁时,如果它已经拥有该锁,则计数器将递增。
    当线程退出同步块时,计数器将递减。
    只有当计数器为零时,该线程才会释放锁。
    因此,如果一个线程在同一对象上多次进入同步块,它将多次获得该锁,并在退出该块时多次释放该锁。因此,synchronized 关键字是可重入的。
  • synchronized 关键字与 lock 机制的比较?
    synchronized 关键字和 Lock 机制都是用来保证线程同步的方法。但是它们有一些明显的差异:

灵活性:Lock 机制比 synchronized 关键字更灵活,因为它提供了更多的锁定操作,例如可以实现公平锁和非公平锁,还可以实现读写锁。
可中断性:Lock 机制可以中断一个线程的等待,而 synchronized 关键字不能。
可重入性:synchronized 关键字是自动可重入的,而 Lock 机制必须手动实现。
性能:如果比较的是相同的锁定操作,synchronized 关键字通常比 Lock 机制更快,因为它是内置的。
总体而言,在简单的同步情况下,synchronized 关键字更方便,但是在需要更多灵活性的情况下,Lock 机制可能是一个更好的选择。

好书推荐

深入理解 Java 高并发编程

修炼高并发内功,面试求职常备。计算机、系统、软件多层次讲透CPU并发、内核并发、Java并发、线程池、JVM原理。

在这里插入图片描述
购书链接:点击传送门

  • 内容简介

《深入理解Java高并发编程》致力于介绍Java高并发编程方面的知识。由于多线程处理涉及的知识内容十分丰富,因此介绍时必须从Java层面的讲解一直深入到底层的知识讲解。为了帮助读者轻松阅读本书并掌握其中知识,本书做了大量基础知识的铺垫。在第1篇基础知识储备中,主要介绍计算机原理、并发基础、常见语言的线程实现、Java并发入门、JUC之Java线程池、JUC之同步结构、Java NIO详解等内容。在第2篇深入Java并发原理中,详细介绍了JUC包中所有使用的原子类的原理与源码实现;非常关键且容易出错的volatile关键字的原理,从Java、JVM、C、汇编、CPU层面对其进行详细讲解;synchronized在JVM中获取锁和释放锁的流程;JUC包的核心结构——AQS的原理与源码实现,通过逐方法、逐行的解释,帮助读者彻底掌握AQS中提供的获取锁、释放锁、条件变量等操作的实现与原理。最后,详细介绍了JVM中JNI的实现原理,将Java Thread对象中的所有方法在JVM层面的实现流程进行了详细描述,以帮助读者在使用这些方法时,知道底层发生了什么,以及发生异常时如何从容解决问题。

  • 作者简介

黄俊,专注于研究Java语言, Hotspot, Linux内核,C语言与汇编,架构设计,多线程并发处理,专注于研究高效学习方式。曾就职于美团、阿里,前新东方业务架构师。

在这里插入图片描述

来源地址:https://blog.csdn.net/qq_54796785/article/details/133913211

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Java 关键字:synchronized详解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

synchronized关键字 - [JAVA心得]

Java对多线程的支持与同步机制深受大家的喜爱,似乎看起来使用了synchronized关键字就可以轻松地解决多线程共享数据同步问题。到底如何?――还得对synchronized关键字的作用进行深入了解才可定论。   总的说来,synchr
2023-06-03

Java关键字synchronized原理与锁的状态详解

在Java当中synchronized关键字通常是用来标记一个方法或者代码块。本文将通过示例为大家详细介绍一下Synchronized的各种使用方法,需要的可以参考一下
2022-11-13

Java中的synchronized关键字怎么用

小编给大家分享一下Java中的synchronized关键字怎么用,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!1、synchronized锁的底层实现原理JVM基于进入和退出Monitor对象来实现方法同步和代码块同步。
2023-06-25

JAVA中native方法与synchronized 关键字

native , synchronized [@more@]JAVA中native方法 @与羊共舞的狼 Java不是完美的,Java的不足除了体现在运行速度上要比传统的C++慢许多之外,Java无法直接访问到操作系统底层(如系统硬件
2023-06-03

Java synchronized同步关键字工作原理

synchronized作为Java程序员最常用同步工具,很多人却对它的用法和实现原理一知半解,以至于还有不少人认为synchronized是重量级锁,性能较差,尽量少用。但不可否认的是synchronized依然是并发首选工具,本文就来详细讲讲
2023-02-13

如何在Java中使用synchronized关键字

如何在Java中使用synchronized关键字?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。java基本数据类型有哪些Java的基本数据类型分为:1、整数类
2023-06-14

synchronized关键字的使用

synchronized关键字是java并发编程中常使用的同步锁,用于锁住方法或者代码块,锁代码块时可以是synchronized(this){}、synchronized(Object){}、synchronized(类class){}。当锁住的内容执行完或
synchronized关键字的使用
2019-02-24

Java多线程synchronized关键字怎么输出

这篇文章主要介绍“Java多线程synchronized关键字怎么输出”,在日常操作中,相信很多人在Java多线程synchronized关键字怎么输出问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java多
2023-06-17

Java多线程并发编程 Synchronized关键字

synchronized 关键字解析同步锁依赖于对象,每个对象都有一个同步锁。现有一成员变量 Test,当线程 A 调用 Test 的 synchronized 方法,线程 A 获得 Test 的同步锁,同时,线程 B 也去调用 Test
2023-05-31

详解Java的static关键字

文章目录 🎄静态方法🌺静态方法和非静态方法对比🛸静态方法实例🛸非静态方法实例 🌹static关键字⭐static变量⭐static代码块
详解Java的static关键字
2023-12-22

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录