一、基本使用

   1.Synchronized的作用。

  • 原子性:确保线程互斥的访问同步代码;
  • 可见性:保证共享变量的修改能够及时可见,其实是通过Java内存模型中的 “对一个变量unlock操作之前,必须要同步到主内存中;如果对一个变量进行lock操作,则将会清空工作内存中此变量的值,在执行引擎使用此变量前,需要重新从主内存中load操作或assign操作初始化变量值” 来保证的;
  • 有序性:有效解决重排序问题,即 “一个unlock操作先行发生(happen-before)于后面对同一个锁的lock操作”

 2.Synchronized的三种用法。Synchronized可以把任何一个非null对象作为"锁"。

  • 当synchronized作用在实例方法时,监视器锁(monitor)便是对象实例(this)
  • 当synchronized作用在静态方法时,监视器锁(monitor)便是对象的Class实例,因为Class数据存在于永久代,因此静态方法锁相当于该类的一个全局锁
  • 当synchronized作用在某一个对象实例时,监视器锁(monitor)便是括号括起来的对象实例。

  3.synchronized与Lock的区别

1.首先synchronized是java内置关键字,在jvm层面,Lock是个java类;

2.synchronized无法判断是否获取锁的状态,Lock可以判断是否获取到锁;

3.synchronized会自动释放锁(a 线程执行完同步代码会释放锁 ;b 线程执行过程中发生异常会释放锁),Lock需在finally中手工释放锁(unlock()方法释放锁),否则容易造成线程死锁;

4.用synchronized关键字的两个线程1和线程2,如果当前线程1获得锁,线程2线程等待。如果线程1阻塞,线程2则会一直等待下去,而Lock锁就不一定会等待下去,如果尝试获取不到锁,线程可以不用一直等待就结束了;

5.synchronized的锁可重入、不可中断、非公平,而Lock锁可重入、可判断、可公平(两者皆可)

6.Lock锁适合大量同步的代码的同步问题,synchronized锁适合代码少量的同步问题。

类别 synchronized Lock
存在层次 Java的关键字,在jvm层面上 是一个类
锁的释放 1、以获取锁的线程执行完同步代码,释放锁 2、线程执行发生异常,jvm会让线程释放锁 在finally中必须释放锁,不然容易造成线程死锁
锁的获取 假设A线程获得锁,B线程等待。如果A线程阻塞,B线程会一直等待 分情况而定,Lock有多个锁获取的方式,具体下面会说道,大致就是可以尝试获得锁,线程可以不用一直等待
锁状态 无法判断 可以判断
锁类型 可重入 不可中断 非公平 可重入 可判断 可公平(两者皆可)
性能 少量同步 大量同步
二、同步原理

1.数据同步需要依赖锁,那锁的同步又依赖谁?

synchronized:在软件层面依赖JVM。

j.u.c.Lock:在硬件层面依赖特殊的CPU指令。

2.监视器锁(monitor):每个对象都是一个监视器锁(monitor)。

  Synchronized的语义底层是通过一个monitor的对象来完成。

3.monitorenter:每个对象都是一个监视器锁(monitor)。当monitor被占用时就会处于锁定状态,线程执行monitorenter指令时尝试获取monitor的所有权。

  • 如果monitor的进入数为0,则该线程进入monitor,然后将进入数设置为1,该线程即为monitor的所有者;
  • 如果线程已经占有该monitor,只是重新进入,则进入monitor的进入数加1;
  • 如果其他线程已经占用了monitor,则该线程进入阻塞状态,直到monitor的进入数为0,再重新尝试获取monitor的所有权;

4.monitorexit:执行monitorexit的线程必须是objectref所对应的monitor的所有者。指令执行时,monitor的进入数减1,如果减1后进入数为0,那线程退出monitor,不再是这个monitor的所有者。其他被这个monitor阻塞的线程可以尝试去获取这个 monitor 的所有权。

三、同步概念

1.Java对象头

  对象在内存中的布局分为三块区域:对象头、实例数据和对齐填充。

  • 实例数据:存放类的属性数据信息,包括父类的属性信息;
  • 对齐填充:由于虚拟机要求 对象起始地址必须是8字节的整数倍。填充数据不是必须存在的,仅仅是为了字节对齐;
  • 对象头Java对象头一般占有2个机器码(在32位虚拟机中,1个机器码等于4字节,也就是32bit,在64位虚拟机中,1个机器码是8个字节,也就是64bit),但是 如果对象是数组类型,则需要3个机器码,因为JVM虚拟机可以通过Java对象的元数据信息确定Java对象的大小,但是无法从数组的元数据来确认数组的大小,所以用一块来记录数组长度。

  

 2.对象头中Mark Word与线程中Lock Record

 3.监视器(Monitor)

 任何一个对象都有一个Monitor与之关联,当且一个Monitor被持有后,它将处于锁定状态。

 Synchronized在JVM里的实现都是 基于进入和退出Monitor对象来实现方法同步和代码块同步。

3.1 MonitorEnter指令:插入在同步代码块的开始位置,当代码执行到该指令时,将会尝试获取该对象Monitor的所有权,即尝试获得该对象的锁;

3.2 MonitorExit指令:插入在方法结束处和异常处,JVM保证每个MonitorEnter必须有对应的MonitorExit;

 参考:深入分析Synchronized原理。

转载于:https://www.cnblogs.com/wenxiangchen/p/11340799.html

并发编程之Synchronized原理相关推荐

  1. 并发编程专题——第二章(并发编程之Synchronized详解)

    日常中我们都会用到Synchronized关键字,但是面试就喜欢问这些,你说不重要吧,面试就不问了,你说重要吧,工作中除了高并发之外,很少能在业务代码中使用到的.所以笔者顶着风险,写下此篇对Synch ...

  2. java并发编程_Java并发编程之 synchronized

    大家好,我是你们的导师,我每天都会在这里给大家分享一些干货内容(当然了,周末也要允许老师休息一下哈).上次老师跟大家分享了下Java中内存泄漏如何分析解决的相关知识,今天跟大家分享Java之 sync ...

  3. 并发编程之Synchronized

    在介绍Synchrinized之前,我们先来了解一下并发的相关概念. 什么是并发? 并发: 同一时间段,多个任务都在执行 (单位时间内不一定同时执行):在同一时刻只会有一条指令执行,但是多个指令被快速 ...

  4. Java并发编程之synchronized关键字解析

    前言 公司加班太狠了,都没啥时间充电,这周终于结束了.这次整理了Java并发编程里面的synchronized关键字,又称为隐式锁,与JUC包中的Lock显示锁相对应:这个关键字从Java诞生开始就有 ...

  5. Java并发编程之ConcurrentHashMap原理解析

    ConcurrentHashMap get: /*** 根据键值key获取value,根据key.equals方法判断两个元素是否相同* @param key 键* @return 如果key存在则返 ...

  6. 并发编程之Exchanger原理与使用

    点赞再看,养成习惯,公众号搜一搜[一角钱技术]关注更多原创技术文章. 本文 GitHub org_hejianhui/JavaStudy 已收录,有我的系列文章. 前言 在JUC包中,除了一些常用的或 ...

  7. 并发编程之LockSupport的 park 方法及线程中断响应

    系列文章目录 Java并发编程技术知识点梳理(第一篇)操作系统底层工作的整体认识 Java并发编程技术知识点梳理(第二篇)并发编程之JMM&volatile详解 Java并发编程技术知识点梳理 ...

  8. 并发编程之 Executor 线程池原理与源码解读

    并发编程之 Executor 线程池原理与源码解读 线程是调度 CPU 资源的最小单位,线程模型分为 KLT 模型与 ULT 模型,JVM使用的是 KLT 模型.java线程与 OS 线程保持 1:1 ...

  9. 深入理解并发编程之CAS无锁机制与ABA问题

    深入理解并发编程之CAS无锁机制与ABA问题 文章目录 深入理解并发编程之CAS无锁机制与ABA问题 前言 一.什么是CAS无锁机制 二.CAS原理分析 1.AtomicLong自增分析 2.基于At ...

最新文章

  1. java 线程的创建和执行_线程管理(一)线程的创建和运行
  2. spss聚类分析_SPSS聚类分析 I K均值聚类法案例实操
  3. 部署LAMP-mysql 安装
  4. 14.refresh操作
  5. 如果把整个因特网都印出来 你认为会怎么样
  6. 交换机用光纤模块互连一端灯不亮或两端都不亮,如何处理?
  7. 论文浅尝 | 利用问题生成提升知识图谱问答
  8. 10-Linux与windows文件互传-pscp坑---- 'pscp' 不是内部或外部命令,也不是可运行的程序或批处理文件...
  9. pytorch使用masked掩盖某些值(筛选值)
  10. 今日恐慌与贪婪指数为68 贪婪程度有所上升
  11. LeetCode 230. 二叉搜索树中第K小的元素(递归)
  12. python显示1000以内的斐波拉契数列_Python 实现斐波那契数列方法及其优化总结
  13. linux下运行exe程序之wine的使用与安装
  14. coreldraw错误代码14001_应用程序配置不正确,应用程序未能启动 提示14001错误代码解决方法...
  15. SGG Trans【Bridging Knowledge Graphsto Generate Scene Graphs】
  16. tableau两个不同的图合并_tableau两个不同的图合并_Tableau数据源详解
  17. latex插入参考文献--BibTex格式
  18. 2021-3-17 Jmeter线程组、运行启动方式
  19. test_and_set_bit
  20. 揭开Storage vMotion的神秘面纱

热门文章

  1. 用工具批量下载哔哩哔哩视频并且将内容转换成pdf
  2. poj2420 A Star not a Tree? 【模拟退火】
  3. 0-1背包问题(一维数组解法)
  4. matlab2015a支持的usb webcams support package
  5. OpenCV2: Mat属性type,depth,step
  6. surf三维画图[matlab]
  7. class多项式(链表实现)
  8. ajax插件库,03.vue-ajax、vue UI 组件库
  9. mailmessage html编码,C#MailMessage顯示HTML標記的AlternateViews
  10. java内存中的栈、方法区 、堆