`
y806839048
  • 浏览: 1127090 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

synchronize原理

阅读更多

目录

 

synchronized的三种应用方式

 

synchronized的字节码指令

 

synchronized的锁的原理

 

Java对象头

 

Monitor

 

synchronized锁的优化

 

自旋锁与自适应自旋

 

锁消除

 

锁粗化

 

偏向锁

 

轻量级锁

 

重量级锁

 

锁升级

 

wait和notify的原理

 

wait和notify为什么需要在synchronized里面?

 

synchronized的三种应用方式

一. 修饰实例方法,作用于当前实例加锁,进入同步代码前要获得当前实例的锁。

 

二. 修饰静态方法,作用于当前类对象加锁,进入同步代码前要获得当前类对象的锁。

 

三. 修饰代码块,指定加锁对象,对给定对象加锁,进入同步代码库前要获得给定对象。

 

synchronized的字节码指令

synchronized同步块使用了monitorenter和monitorexit指令实现同步,这两个指令,本质上都是对一个对象的监视器(monitor)进行获取,这个过程是排他的,也就是说同一时刻只能有一个线程获取到由synchronized所保护对象的监视器。

 

线程执行到monitorenter指令时,会尝试获取对象所对应的monitor所有权,也就是尝试获取对象的锁,而执行monitorexit,就是释放monitor的所有权。

 

synchronized的锁的原理

两个重要的概念:一个是对象头,另一个是monitor。

 

Java对象头

在Hotspot虚拟机中,对象在内存中的布局分为三块区域:对象头(Mark Word、Class Metadata Address)、实例数据和对齐填充;Java对象头是实现synchronized的锁对象的基础。一般而言,synchronized使用的锁对象是存储在Java对象头里。它是轻量级锁和偏向锁的关键。

 

Mark Word

Mark Word用于存储对象自身的运行时数据,如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的

锁、偏向线程 ID、偏向时间戳等等。Java对象头一般占有两个机器码(在32位虚拟机中,1个机器码等于4字节,

也就是32bit)。

 

 

Class Metadata Address

类型指针,即是对象指向它的类的元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。

 

Array length

如果对象是一个Java数组,那在对象头中还必须有一块用于记录数组长度的数据。

 

Monitor

Monitor是一个同步工具,它内置于每一个Object对象中,相当于一个许可证。拿到许可证即可以进行操作,没有拿到则需要阻塞等待。

 

在hotspot虚拟机中,通过ObjectMonitor类来实现monitor。

 

类似netty一个woker工作模型

 

synchronized锁的优化

jdk1.6以后对synchronized的锁进行了优化,引入了偏向锁、轻量级锁,锁的级别从低到高逐步升级: 

 

无锁->偏向锁->轻量级锁->重量级锁

 

自旋锁与自适应自旋

线程的挂起和恢复会极大的影响开销。并且jdk官方人员发现,很多线程在等待锁的时候,在很短的一段时间就获得了锁,所以它们在线程等待的时候,并不需要把线程挂起,而是让他无目的的循环,一般设置10次。这样就避免了线程切换的开销,极大的提升了性能。

 

而适应性自旋,是赋予了自旋一种学习能力,它并不固定自旋10次一下。他可以根据它前面线程的自旋情况,从而调整它的自旋,甚至是不经过自旋而直接挂起。

 

手动wait就是直接挂起,需要notify,如果只是没有争夺到引起的阻塞实际是自旋--升级成重锁之后阻塞

 

锁消除

对不会存在线程安全的锁进行消除。

 

锁粗化

如果jvm检测到有一串零碎的操作都对同一个对象加锁,将会把锁粗化到整个操作外部,如循环体。

 

偏向锁

多数情况下,锁不仅不存在多线程竞争,而且总是由同一线程多次获得,为了让其获得锁的代价更低而引入了偏向锁。

 

当一个线程访问同步块并获取锁时,会在对象头和栈帧中的锁记录里存储锁偏向的线程ID,以后该线程在进入和退出同步块时不需要进行CAS操作来加锁和解锁,只需简单地测试一下对象头的Mark Word里是否存储着指向当前线程的偏向锁。(类似cas认证

 

如果测试成功,表示线程已经获得了锁。

 

如果测试失败,则需要再测试一下Mark Word中偏向锁的标识是否设置成01(表示当前是偏向锁)。

 

如果没有设置,则使用CAS竞争锁。

 

如果设置了,则尝试使用CAS将对象头的偏向锁指向当前线程。

 

轻量级锁

引入轻量级锁的主要目的是在多线程竞争不激烈的情况下,通过CAS竞争锁,减少传统的重量级锁使用操作系统互斥量产生的性能消耗。

 

重量级锁

重量级锁通过对象内部的监视器(monitor)实现,其中monitor的本质是依赖于底层操作系统的Mutex Lock实现,操作系统实现线程之间的切换需要从用户态到内核态的切换,切换成本非常高。

 

锁升级

偏向锁升级轻量级锁:当一个对象持有偏向锁,一旦第二个线程访问这个对象,如果产生竞争,偏向锁升级为轻量级锁。

 

轻量级锁升级重量级锁:一般两个线程对于同一个锁的操作都会错开,或者说稍微等待一下(自旋),另一个线程就会释放锁。但是当自旋超过一定的次数,或者一个线程在持有锁,一个在自旋,又有第三个来访时,轻量级锁膨胀为重量级锁,重量级锁使除了拥有锁的线程以外的线程都阻塞,防止CPU空转。

 

wait和notify的原理

调用wait方法,首先会获取监视器锁,获得成功以后,会让当前线程进入等待状态进入等待队列并且释放锁。

 

当其他线程调用notify后,会选择从等待队列中唤醒任意一个线程,而执行完notify方法以后,并不会立马唤醒线程,原因是当前的线程仍然持有这把锁,处于等待状态的线程无法获得锁。必须要等到当前的线程执行完按monitorexit指令以后,也就是锁被释放以后,处于等待队列中的线程就可以开始竞争锁了。

 

wait和notify为什么需要在synchronized里面?---synchronized 是非公平锁,可以重入。

wait方法的语义有两个,一个是释放当前的对象锁、另一个是使得当前线程进入阻塞队列,而这些操作都和监视器是相关的,所以wait必须要获得一个监视器锁。

 

而对于notify来说也是一样,它是唤醒一个线程,既然要去唤醒,首先得知道它在哪里,所以就必须要找到这个对象获取到这个对象的锁,然后到这个对象的等待队列中去唤醒一个线程。

--------------------- 

 

原文链接:https://blog.csdn.net/u011212394/article/details/82228321

分享到:
评论

相关推荐

    delphi vcl线程同步synchronize

    本文将深入探讨Delphi VCL线程同步以及Synchronize方法的工作原理、使用场景和最佳实践。 ### 1. 线程同步基础 在多线程环境中,多个线程可能同时访问同一资源,这可能导致数据不一致或者竞态条件。为了防止这些...

    Java synchronize底层实现原理及优化

    Java synchronize 底层实现原理及优化 在 Java 中,synchronize 是一种锁机制,用于控制并发冲突,避免多个线程同时访问同一个资源。synchronize 底层实现原理及优化是 Java 并发编程中一个重要的概念,本文将详细...

    synchronize底层实现原理

    synchronize底层实现原理 Java文件想要看字节码通常使用 javap 命令将java的class文件反汇编,具体操作步骤如下: 1. 先写好一个SynchronizedTest.java文件(下面贴出) 2. 在java文件的目录下,使用命令 javac ...

    DXP层次原理图设计.docx

    然后,通过选择DESIGN -> Synchronize Sheet Entries and Ports (DP)将port同步到主图中。这使得主图能够识别子图的输入和输出。 3. **NET和Port的一一对应**:虽然NET和Port可以使用不同的名称,但为了清晰和准确...

    Synchronize Your System Time with a Network Time Protocol (N

    源码对于开发者来说非常有价值,因为它允许他们理解同步过程的工作原理,以及如何在自己的应用程序中集成类似的功能。 “网络通信类”暗示了这个项目可能包含了一些处理网络通信的类,这些类可能封装了与NTP服务器...

    synchronize.pdf

    标题 "synchronize.pdf" 和描述 "synchronize详解" 显示该文档专注于Java编程语言中关键字 synchronized 的使用和机制。Synchronized 关键字是Java中用于控制多线程并发访问共享资源的一个核心关键字,确保同一时间...

    Altium Designer之多图纸设计

    当子图纸中的端口与图纸入口不匹配时,可以通过“Design》Synchronize Sheet Entries and Ports”来同步。 2.3 重命名图表符对应的子图纸 可以通过“Design》Rename Child Sheet”功能来重命名图表符对应的子图纸...

    基于tcp的端口扫描原理与实现.pdf

    基于 TCP 的端口扫描原理与实现 基于 TCP 的端口扫描原理与实现是指通过使用 TCP 协议来扫描指定主机的端口是否开放的一种技术。这种技术主要应用于网络协议和计算机安全领域。 工作原理: 基于 TCP 协议的网络...

    DXP层次原理图设计.doc

    - 使用`DESIGN -> Synchronize sheet entries and Ports (DP)`命令将port同步到主图中。 - PORT和NET可以不对应,但最好保持同名以简化连接。 - 在非层次原理图中,同一项目的不同sheet的NETlabel可以连接,但在...

    Synchronize

    在IT行业中,"Synchronize"通常指的是同步操作,这是一个关键概念,特别是在多线程编程、数据库管理和网络通信等领域。...理解和掌握同步原理与技术,对于提高IT专业人员的工作效率和项目质量具有重要意义。

    Backup and Synchronize-开源

    描述进一步解释了这个工具的工作原理。它利用了两个强大的命令行工具——RSYNC和ROBOCOPY,分别用于Linux和macOS以及Windows系统。RSYNC是Unix和Linux环境中广泛使用的文件同步工具,以其高效、灵活和增量备份功能...

    Java对象锁和类锁全面解析(多线程synchronize

    在这个全面解析中,我们将深入探讨这两个锁机制,理解它们的工作原理以及如何在实际开发中有效应用。 首先,对象锁是针对对象级别的锁定,它保护的是实例方法或者一个特定的代码块。当一个线程进入一个由`...

    Java-Interview:此项目为 Java 面试的汇总,多数是一些 Java 基础知识、底层原理、算法详解。也有上层应用设计,其中不乏一些大厂面试真题

    synchronize 关键字原理 多线程的三大核心 对锁的一些认知 ReentrantLock 实现原理 ConcurrentHashMap 的实现原理 线程池原理 深入理解线程通信 交替打印奇偶数 JVM Java 运行时内存划分 类加载机制 OOM 分析 垃圾...

    java技术储备,如何提升自己

    1. Synchronize 和 Lock:了解 Synchronize 和 Lock 的区别与用法。 2. wait() 和 notify():了解 wait() 和 notify() 的区别和用法。 3. volatile:深入理解 volatile 关键字的作用和实现机制。 4. CAS:了解 CAS...

    delphi中线程同步问题

    本文将深入探讨 `Synchronize` 的工作原理,并提出解决 DLL/ActiveForm 中线程同步问题的策略。 `Synchronize` 的实现基于事件和线程同步原语。当一个非主线程调用 `Synchronize` 时,它会创建一个同步记录结构,...

    orcad学习笔记

    orcad学习笔记:orCAD中层次原理图如何同步pin及port? 1.子原理图中加好port后,点击根...2.或者根原理图中加好pin后,点击根原理图,选择对应hiererchy,右击选择synchronize down,port会出现在子原理图的右上角。

    三次握手协议的原理及实现

    【三次握手协议的原理及实现】 TCP/IP协议是互联网通信的基础,其中TCP(Transmission Control Protocol)传输控制协议是其核心部分,提供了可靠的、面向连接的数据传输服务。TCP通过三次握手来建立连接,确保数据...

    (完整版)异步FIFO设计.pdf

    同步模块可以分为两部分:synchronize to write clk 和 synchronize to read clk。synchronize to write clk 的作用是把读时钟域的读指针 rd_ptr 采集到写时钟域,然后和写指针 wr_ptr 进行比较从而产生或撤消写满...

    两层PCB设计基础--学习笔记.pdf

    4. 检查端口对应:Design>Synchronize sheet Entries and Ports,提示匹配则正确。 5. 底层到顶层:在顶层原理图中,右键Sheet actions Creat Sheet symbol from sheet or HDL。 6. 总线处理:总线需放置网络标号,...

    设置虚拟系统时间不随本地系统时间变化

    #### 虚拟机时间同步原理 在大多数情况下,虚拟机管理系统(如VMware、VirtualBox等)默认情况下都会开启时间同步功能,这样做的目的是为了确保虚拟机中的时间与宿主机的时间保持一致。时间同步通常是通过虚拟机...

Global site tag (gtag.js) - Google Analytics