java中synchronized关键字基础-1
1、synchronized关键字简介
synchronized是java中的一个关键字,在中文中为同步,也被称之为'同步锁',以此来达到多线程并发访问时候的并发安全问题,可以用来修饰代码块、非静态方法。静态方法等;
修饰代码块时:给当前指定的对象加锁
修饰非静态方法时:作用于当前实例加锁
修饰静态方法时:作用于当前类对象加锁
synchronized在java内存模型中的主要作用
原子性:通过monitorenter和monitorexit指令,保证被synchronized修饰的代码在同一时间只能被一个线程访问,在锁未释放之前,无法被其他线程访问到
可见性:保证共享变量的修改能够及时可见,对一个变量的unlock操作之前,必须把此变量同步回主内存中(store和write操作)
有序性:一个变量在同一时刻只允许一条线程对其执行lock操作,这条规则决定了持有同一个锁的两个同步块只能串行执行
2、synchronized修饰代码块
当synchronized修饰代码块时,有以下几种情况
1、this关键字
synchronized(this){ //互斥代码 `` }
这里的this就是等价于调用这个方法的对象,synchronized锁的就是this这个对象的锁,若有多个对象调用方法,各个对象锁之间相互独立,互不影响
2、Class.class
synchronized(Test.class){ //互斥代码
} 这里synchronized锁的对象为类锁,在需要类锁的代码不能同时执行,但是与非需要类锁的对象锁或者与没有加锁的代码可以同时执行 用synchronized进行加锁时看获得锁是对象还是类的锁,还有的是synchronized锁住的是一个对象或者类(其实也是对象),而不是方法或者代码段。 3、synchronized修饰实例方法 public synchronized void method(){ //代码 }
当synchronized修饰实例方法时,锁的是该类的实例对象
4、synchronized修饰静态方法
public synchronized static void method() { // todo
`` }
由于static静态方法是属于类的而不属于对象的,所以synchronized修饰的静态方法锁定的是这个类的所有对象
5、synchronized的底层实现原理
在java内存模型中,synchronized可以保证原子性、有序性、可见性,在这之前,先谈谈对象在HotSpot虚拟机中的分布,主要有三部:对象头(Header)、实例数据(Instance Data)和对象填充(Padding)
对象头
对象头主要包括两部分信息,第一部分用于存储对象自身的运行时数据、如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等,官方称之为'Mark Word',还有一部分称之为类型指针,即对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例
存储内容标志位状态对象哈希码、对象分代年龄01未锁定指向锁记录的指针00轻量级锁定指向重量级锁的指针10膨胀(重量级锁定)空,不需要记录信息11GC标识偏向线程ID、偏向时间戳、对象分代年龄01可偏向
实例数据
实例数据部分是对象真正存储的有效信息,即我们在程序代码里面所定义的各种类型的字段内容,无论是从父类继承下来的,还是在子类中定义的字段都必须记录起来。这部分的存储顺序会受到虚拟机分配策略参数(-XX: FieldsAllocationStyle) 和字段在Java源码中定义顺序的影响。
对齐填充
对齐填充并不是必然存在的,也没有特别的含义,仅仅只是起着占位符的作用,由于HotSpot VM的自动内存管理系统要求对象起始地址必须是8字节的整数倍,就是对象的大小必须是8字节的整数倍,而对象头部分正好是8字节的倍数(1倍或者2倍),因此,当对象实例数据部分没有对齐时,就需要通过对齐填充来补全。
原子性
synchronized实现原子性底层是通过JVM来实现的,同一时间只能有一个线程去执行synchronized中的代码块;
每一个对象都有一个监视器monitor来关联,监视器被占用时会被锁住,其他线程无法获取该monitor,当JVM执行某个线程的的内部方法的monitorenter,它会尝试去获取该对象的monitor的所有权,过程如下
1、若monitor的进入数为0,线程可以进入monitor,并将该monitor的进入数置为1,那么该线程就成为monitor的所有者
2、若线程已拥有monitor的所有权,允许它重入monitor,则进入monitor的进入数加1(recursions:记录线程拥有锁的次数)
3、若其他线程已经占有monitor的所有权,那么当前尝试获取monitor的所有权的线程会被阻塞,直到monitor的进入数变为0,才能重新尝试获取monitor的所有权。
monitorexit指令
1、能执行monitorexit指令的线程一定是拥有当前对象的monitor的所有权的线程。
2、当执行monitorexit时会将monitor的进入数减1。当monitor的进入数减为0时,当前线程退出monitor,不再拥有monitor的所有权,此时这个monitor阻塞的线程可以尝试去获取这个monitor的所有权。
可见性
synchronized通过内存屏障保证可见性,同样的我们知道volatile是通过内存屏障来保证可见性的,
1、monitorenter指令之后,synchronized内部的共享变量,每次读取数据的时候被强制从主内存读取最新的数据。
2、monitorexit指令也具有Store屏障的作用,也就是让synchronized代码块内的共享变量,如果数据有变更的,强制刷新回主内存。
数据修改之后立即刷新回主内存,其他线程进入synchronized代码块后,使用共享变量的时候强制读取主内存的数据。
有序性
同样的,synchronized也是通过monitorenter、monitorexit指令嵌入上面的内存屏障,既具有加锁、释放锁的功能,同时也具有内存屏障的功能
java中synchronized关键字基础-1的更多相关文章
- java中synchronized关键字分析
今天我们来分析一下java中synchronized关键字.首先来看一段java代码:(本地编译环境为mac,jdk1.8的环境) Demo.java package com.example.spri ...
- Java中synchronized关键字理解
好记性不如烂笔头~~ 并发编程中synchronized关键字的地位很重要,很多人都称它为重量级锁.利用synchronized实现同步的基础:Java中每一个对象都可以作为锁.具体表现为以下三种形式 ...
- java中synchronized关键字的用法
在java编程中,经常需要用到同步,而用得最多的也许是synchronized关键字了,下面看看这个关键字的用法. 因为synchronized关键字涉及到锁的概念,所以先来了解一些相关的锁知识. j ...
- Java关键字-----------------java中synchronized关键字的用法
在java编程中,经常需要用到同步,而用得最多的也许是synchronized关键字了,下面看看这个关键字的用法. 因为synchronized关键字涉及到锁的概念,所以先来了解一些相关的锁知识. j ...
- Java中synchronized关键字你知道多少
1.什么是synchronized 我们将其理解为同步锁,可以实现共享资源的同步访问,解决线程并发的安全问题.synchronize翻译成中文:同步,使同步.synchronized:已同步. 1.1 ...
- Java的synchronized关键字:同步机制总结
JAVA中synchronized关键字能够作为函数的修饰符,也可作为函数内的语句,也就是平时说的同步方法和同步语句块.搞清楚synchronized锁定的是哪个对象,就能帮助我们设计更安全的多线程程 ...
- 从分布式锁角度理解Java的synchronized关键字
分布式锁 分布式锁就以zookeeper为例,zookeeper是一个分布式系统的协调器,我们将其理解为一个文件系统,可以在zookeeper服务器中创建或删除文件夹或文件.设D为一个数据系统,不具备 ...
- 008 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 02 Java 中的关键字
008 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 02 Java 中的关键字 关键字 关键字就是一些有特殊意义的词 之前学习的程序中涉及到的关键字 Java中 ...
- 【Java_基础】Java中Native关键字的作用
本篇博文转载与:Java中Native关键字的作用
随机推荐
- Java JDK 动态代理实现和代码分析
JDK 动态代理 内容 一.动态代理解析 1. 代理模式 2. 为什么要使用动态代理 3. JDK 动态代理简单结构图 4. JDK 动态代理实现步骤 5. JDK 动态代理 API 5.1 java ...
- JavaScript实现指定格式字符串表单校验
运行效果: 源代码: 1 <!DOCTYPE html> 2 <html lang="zh"> 3 <head> 4 <meta char ...
- C# 一个基于.NET Core3.1的开源项目帮你彻底搞懂WPF框架Prism
--概述 这个项目演示了如何在WPF中使用各种Prism功能的示例.如果您刚刚开始使用Prism,建议您从第一个示例开始,按顺序从列表中开始.每个示例都基于前一个示例的概念. 此项目平台框架:.NET ...
- git概述
学习资料来源-人家写得比我好 #视频教程: https://www.bilibili.com/video/BV1vy4y1s7k6?spm_id_from=pageDriver #文档教程 https ...
- 脏数据清洗,pandas.apply()的应用
原数据如下所示: IMAGETYPE count .?+? 1713 Jh.5? 100 .??U 38 .11.1 1 .13.1 1 .15.11 2 我需要对数据内的带有特殊符号,且第一个逗号 ...
- Struts2中将表单数据封装到List和Map集合中
一.将表单数据封装到Map集合中 1.创建MapAction类 import cn.entity.User; import com.opensymphony.xwork2.ActionSupport; ...
- 帝国cms 列表页或文章页取当前栏目链接
获取当前栏目链接 : <?=sys_ReturnBqClassUrl($class_r[$GLOBALS[navclassid]]);?>获取当前栏目名称 :[!--class.name- ...
- 【图文教学】如何轻松下载tiktok上的视频
我是真诚的想和大家分享这个办法的!这个叫光影存图,图标就是这个绿色的箭头,我是苹果手机,安卓手机也可以用,就是它分免费版和会员版的,没有强制要你充会员,看一下广告就可以获取下载次数,我就是这么干的,只 ...
- 关于croptool无法裁剪分辩率过低的图片
在使用croptool.js时,如果图片的分辨率过低,则无法裁剪超过分辨率的大小.比如说 function chooseImg(event){ var files = event.files || e ...
- 认识python-个人笔记篇
认识python 1 .python 的发展历史 一种广泛使用的解释型.高级编程.通用型编程语言,由"龟叔"吉多·范罗苏姆创造,第一版发布于1991年. Python的设计哲学强调 ...