Python 官方文档:入门教程 => 点击学习
目录一、synchronized介绍二、synchronized的使用1.修饰方法三、synchronized的底层实现对象头监视器(Monitor)四、synchronized 锁
synchronized
中文意思是同步,也称之为”同步锁“。
synchronized
的作用是保证在同一时刻, 被修饰的代码块或方法只会有一个线程执行,以达到保证并发安全的效果。
synchronized
是Java中解决并发问题的一种最常用的方法,也是最简单的一种方法。
在jdk1.5之前synchronized
是一个重量级锁,相对于j.u.c.Lock
,它会显得那么笨重,随着Javs SE 1.6对synchronized
进行的各种优化后,synchronized
并不会显得那么重了。
synchronized
的作用主要有三个:
happen-before
)于后面对同一个锁的lock操作”;synchronized的3种使用方式:
Synchronized
修饰一个方法很简单,就是在方法的前面加synchronized
,synchronized
修饰方法和修饰一个代码块类似,只是作用范围不一样,修饰代码块是大括号括起来的范围,而修饰方法范围是整个函数。
public synchronized void method()
{
// todo
}
public void method()
{
synchronized(this) {
// todo
}
}
方法一与方法二是等价的,都是锁定了整个方法时的内容。
synchronized
关键字不能继承。虽然可以使用synchronized
来定义方法,但synchronized
并不属于方法定义的一部分,因此,synchronized
关键字不能被继承。
synchronized
关键字class Parent {
public synchronized void method() { }
}
class Child extends Parent {
public synchronized void method() { }
}
class Parent {
public synchronized void method() { }
}
class Child extends Parent {
public void method() { super.method(); }
}
注意:
synchronized
关键字。synchronized
关键字,但可以使用synchronized
代码块来进行同步。当有一个明确的对象作为锁时,就可以用类似下面这样的方式写程序:
public void method3(SomeObject obj)
{
//obj 锁定的对象
synchronized(obj)
{
// todo
}
}
当没有明确的对象作为锁,只是想让一段代码同步时,可以创建一个特殊的对象来充当锁:
class Test implements Runnable
{
private byte[] lock = new byte[0]; // 特殊的instance变量
public void method()
{
synchronized(lock) {
// todo 同步代码块
}
}
public void run() {
}
}
synchronized
也可修饰一个静态方法,用法如下:
public synchronized static void method() {
// todo
}
Synchronized
还可作用于一个类,用法如下:
class ClassName {
public void method() {
synchronized(ClassName.class) {
// todo
}
}
}
使用总结
synchronized
关键字加在方法上还是对象上,如果它作用的对象是非静态的,则它取得的锁是对象;如果synchronized
作用的对象是一个静态方法或一个类,则它取得的锁是对类,该类所有的对象同一把锁。谈synchronized
的底层实现,就不得不谈数据在JVM内存的存储:Java对象头,以及Monitor对象监视器。
在JVM中,对象在内存中的布局分为三块区域:对象头、实例数据和对齐填充。如下图所示:
synchronized
用的锁就是存在Java对象头里的,那么什么是Java对象头呢?Hotspot虚拟机的对象头主要包括两部分数据:Mark Word(标记字段)、Class Pointer
(类型指针)。
其中 Class Pointer
是对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例,Mark Word用于存储对象自身的运行时数据,它是实现轻量级锁和偏向锁的关键。
任何一个对象都有一个Monitor与之关联,当且一个Monitor被持有后,它将处于锁定状态。
synchronized
在JVM里的实现都是 基于进入和退出Monitor对象来实现方法同步和代码块同步,虽然具体实现细节不一样,但是都可以通过成对的MonitorEnter
和MonitorExit
指令来实现。
MonitorEnter
必须有对应的MonitorExit
;那什么是Monitor?可以把它理解为 一个同步工具,也可以描述为 一种同步机制,它通常被描述为一个对象。
与一切皆对象一样,所有的Java对象是天生的Monitor,每一个Java对象都有成为Monitor的潜质,因为在Java的设计中 ,每一个Java对象自打娘胎里出来就带了一把看不见的锁,它叫做内部锁或者Monitor锁。
也就是通常说Synchronized
的对象锁,MarkWord锁标识位为10,其中指针指向的是Monitor对象的起始地址。在Java虚拟机(HotSpot)中,Monitor是由ObjectMonitor
实现的。
锁解决了数据的安全性,但是同样带来了性能的下降。hotspot 虚拟机的作者经过调查发现,大部分情况下,加锁的代码不仅仅不存在多线程竞争,而且总是由同一个线程多次获得。所以基于这样一个概率。
synchronized
在JDK1.6 之后做了一些优化,为了减少获得锁和释放锁来的性能开销,引入了偏向锁、轻量级锁、自旋锁、重量级锁,锁的状态根据竞争激烈的程度从低到高不断升级。
锁主要存在四种状态,依次是:无锁状态、偏向锁状态、轻量级锁状态、重量级锁状态,锁可以从偏向锁升级到轻量级锁,再升级的重量级锁。但是锁的升级是单向的,也就是说只能从低到高升级,不会出现锁的降级。而且这个过程就是开销逐渐加大的过程。
到此这篇关于浅谈Java的Synchronized锁原理和优化 的文章就介绍到这了,更多相关Synchronized锁原理和优化 内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
--结束END--
本文标题: 浅谈Java的Synchronized锁原理和优化
本文链接: https://www.lsjlt.com/news/213980.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
下载Word文档到电脑,方便收藏和打印~
2024-03-01
2024-03-01
2024-03-01
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0