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中求一下2008年5月31日, 往前倒30天是哪天?
题目9: 2008年5月31日, 往前倒30天是哪天? import java.util.*; public class Test { public static void main(Str ...
- 小程序中引入iconfont
注释:本人喜欢 font class, 你们可以依葫芦画瓢unicode和 symbol,,下面是 font class 演示: 1.选择好图标,然后: font class 2.步骤二: 复制 ...
- 深度学习(三)之LSTM写诗
目录 数据预处理 构建数据集 模型结构 生成诗 根据上文生成诗 生成藏头诗 参考 根据前文生成诗: 机器学习业,圣贤不可求.临戎辞蜀计,忠信尽封疆.天子咨两相,建章应四方.自疑非俗态,谁复念鹪鹩. 生 ...
- JWT&RSA实现单点登录(详细介绍)
今天给大家讲一下基于JWT&RSA的单点登录(Single Sign On,简称SSO)解决方案 概念 首先要了解几个概念 单点登录(Single Sign On) JWT RSA 背景 为什 ...
- Docker入门(windows版),利用Docker创建一个Hello World的web项目
Docker 当大家点开这篇博客的时候,相信大家对docker多多少少也有些认识了,最近学习docker这门技术,略微有些心得,写篇文章记录一下学习过程并帮大家跳过一些坑. docker的核心有两个, ...
- Python入门-字符串格式化
一.不推荐使用:%号 #正常按照位置传递参数 print('%s asked %s to do something' % ('egon', 'lili')) #先后顺序不能乱 #字典传递参数 prin ...
- Spring Boot配置druid监控页功能
1.导入坐标 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http ...
- Spring原始注解开发-02
使用@Repository.@Service.@Controller注解配置,使其更加清晰属于哪一层,因为我是模拟的web层,所有没有使用@Controller注解,后面结合web开发会使用到 1.创 ...
- ajax - 终结篇jsonp,防抖节流
今天是我们最后一天ajax的学习,这次学完总可以去vue了吧,我不信还有什么拦路石,先不说其他的先看看今天的内容. 1. 首先是同源策略,什么叫做同源? 如果两个页面的协议.域名.端口都相同的话,我们 ...
- Codeforces Round #771 (Div. 2), problem: (B) Odd Swap Sort
Problem - B - Codeforces 就是给你个序列, 给他整成升序的, 每次操作可以使相邻两个数交换位置, 交换条件是二数之和为奇数 结果只需输出是否可以整成升序的 思路: 需要奇数偶数 ...