Synchronized关键字的原理分析

news/2024/5/17 15:21:45 标签: synchronized

Synchronized的使用方式


1.当synchronized修饰非静态方法时,锁住的是当前调用该方法的实例对象

2.当synchronized修饰的是非静态代码块,则锁住的是括号里面的实例对象 

3.当synchronized修饰的是静态方法或者静态代码块时,则锁住的是类对象,因为不管一个class被

实例化多少次,静态方法和静态代码块在jvm中只会存在一份,因此当此类的所有实例对象在调用静态方法

或者静态代码块时共用同一把锁,因此也称为类锁

Synchronized的底层原理


synchronized是基于JVM内置锁实现的,通过内部对象Monitor(监视器锁)实现,基于进入和退出Monitor对

象来实现方法和代码块的同步。这是一个重量级锁,性能偏低。

Java1.5版本之后做了很大的变化,比如锁粗化,锁消除,偏向锁,轻量级锁,适应性自旋锁等技术来减少操作

的开销。synchronized性能已经有很大的提升了,已基本和Lock持平。

每个对象都有一个自己的Monitor监视器锁

 

Java对象在内存中的存储方案


HotSpot虚拟机中,对象在内存中被划分成三块区域存储:

1.对象头:比如hash码,对象所属的年代,对象锁,锁标识,偏向锁(线程)ID等。

2.实例数据:即创建对象时,对象中的成员变量,方法等。

3.对象填充:对象的大小必须是8字节的整数倍 

以32位计算机为例,对象头中Mark Word的变化过程如下所示:

锁的膨胀升级过程


锁的状态总共有四种,无锁,偏向锁,轻量级锁,重量级锁。随着多个线程竞争共享资源,锁可以从偏向锁升级到

轻量级锁,再升级到重量级锁,而且这个过程是单向的,不可逆的。也就说锁只能从低到高升级,而不会出现锁降级。

  • 偏向锁

偏向锁时jdk1.6之后加入的新锁,它是一种针对加锁操作的优化手段。经研究发现,大多数情况下,锁不仅不存在

多线程竞争,而写总是由同一线程多次获得锁,因此为了减少同一线程获取锁时进行的一些CAS操作而消耗一定的性能而

引入偏向锁。

偏向锁的核心思想是,如果一个线程获取了锁,那么锁就进入偏向该线程的模式,此时对象的Mark Word结构也

会变为偏向锁结构,当这个线程再次申请该锁时,无需做任何操作,即可获得该锁的使用权,这样就省去了大量的有关

申请锁的操作,从而提高程序的性能。

偏向锁的适用场景是对于锁的竞争不是很激烈的场合。

偏向锁失败后,不会立即升级为重量级锁,而是变成轻量级锁。

  • 轻量级锁

从偏向锁升级成轻量级锁后,对象的Mark Word也会发生变化.

轻量级锁的依据是:对加锁的整个周期内的绝大部分时间不存在竞争,另一个线程自旋等待锁资源释放,不会交出

CPU使用权。

轻量级锁的适用场景是多个线程交替执行同步块的情况,如果同一时间有多个线程竞争锁资源的话,就会升级成

重量级锁.

  • 自旋锁

自旋锁的实现是进行一定次数的空循环,一般是50次或者100个循环,在经过若干次循环后,如果得到锁,进进入

临界区,如果还不能获取到锁,就会将线程在操作系统层面挂起。

  • 锁消除

Java虚拟机在JIT编译时,通过对运行上下文的扫描,去除不可能存在共享资源竞争的锁,通过这种方式消除

没有必要的锁,可以节省毫无意义的请求锁时间,如下StringBuffer的append是一个同步方法,但是在add方法中的

StringBuffer属于一个局部变量,并且不会被其他线程所使用,因此StringBuffer不可能存在共享资源竞争的情景,

JVM会自动将其锁消除


http://www.niftyadmin.cn/n/1277670.html

相关文章

TCP/IP详解学习笔记(10)-TCP连接的建立与中止

TCP是一个面向连接的协议,所以在连接双方发送数据之前,都需要首先建立一条连接。这和前面讲到的协议完全不同。前面讲的所有协议都只是发送数据而已,大多数都不关心发送的数据是不是送到,UDP尤其明显,从编程的角度来说…

OpenGL-------状态机

状态机就是一种存在于理论中的机器,它具有以下的特点: 1. 它有记忆的能力,能够记住自己当前的状态。 2. 它可以接收输入,根据输入的内容和自己的状态,修改自己的状态,并且可以得到输出。 3. 当它进入某个特…

搭建通用的SSM框架 (六) 使用POI下载Excel文件

1.引入jar包 <dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.0.0</version></dependency> 2.开发Controller&#xff0c;从Controller类可以得出需要创建CityExportUtil类 pa…

【贪心】SOJ 13983

SOJ 13983. Milk Scheduling 这是比赛题&#xff0c;还是作死的我最讨厌的英文题&#xff0c;题目大意就是有n头奶牛&#xff0c;要在喂奶截止时间前给他喂奶并得到相应的含量的牛奶。一开始的想法就是挑选截止日期的最大产奶量的那头牛喂养&#xff0c;后来果不其然的WA了。空…

Java 多线程线程池-ThreadPoolExecutor的execute方法分析

0.ThreaPoolExecutor的类图 1.线程池类的一些重要属性 //AtomicInteger占位32位private final AtomicInteger ctl new AtomicInteger(ctlOf(RUNNING, 0));private static final int COUNT_BITS Integer.SIZE - 3;private static final int CAPACITY (1 << COUNT_BIT…

USB Key

随着互联网和电子商务的发展&#xff0c;USB Key作为网络用户身份识别和数据保护的“电子钥匙”&#xff0c;正在被越来越多的用户所认识和使用。本文对USB Key的产生和未来的发展趋势作了一个简单的介绍。 目前市场上见到的USB Key 按照硬件芯片不同可以分为使用智能卡芯片的和…