现在集群,分布式,微服务这么火,基本上也不会有单机服务了,所以synchronized基本上就废了,但不影响我们再回忆一下他的一些思想,很多东西,万变不离其宗。

概念:

能够保证同一时刻最多只有一个线程执行该段代码,以达到保证并发安全的作用。

核心思想:

1、一个锁只能同时被一个线程获取,没拿到锁的线程必须等待
2、每个实例都对应自己的一把锁,不同实例的锁互不影响。
3、如果锁对象是*.class或者synchronized修饰静态方法时,所有对象其实是共用一把锁,这把锁也叫类锁。
4、锁住的方法如果抛出异常,JVM会自动释放锁。

性质

1、可重入
同一线程的外层函数获得锁后,内层函数可以直接再次获取该锁
好处:避免死锁,提高封装线性
2、不可中断
一旦这个锁被别人获得,那么我如果想获得这个锁,只能选择等待或者阻塞,直到别人释放了这个锁
相比Lock可中断,这个synchronized就是等到死。

原理

加锁和释放锁,其实就是操作内置锁,等价于lock的lock方法和unlock方法。
每个对象,都有一个对象头,对象头中可以存很多信息,其中有一个就是synchronized的信息。
javac test.java
javap -verbose test.class
对于加锁的,我们可以在反编译中看到两个指令,monitorenter和monitorexit。
这两个指令,就相当于Lock锁的lock方法和unlock方法。
monitor可以理解是个计数器,
计数器初始为0,0代表可以获取锁。
当一个线程获取锁,对应的就是执行monitorenter指令,计数器+1
同一个线程如果重入,就继续+1,多次重入就多次+1
当退出锁方法,对应的就是执行monitorexit指令,计数器-1
如果有重入的,那就退一个就-1,计数器减到0,就代表释放锁。
如果计数器不为0,那么其他线程尝试获取锁,就会获取不到。

synchronized保证可见性

我们知道线程之间的通信,是通过主内存通信的,而其实每个线程都有自己的本地变量的副本,加这一层就是为了快,类似于缓存,那只要是缓存,就会出现缓存不一致。
而使用了synchronized关键字后,就会无视这层缓存,比如一个对象被锁住,那么锁住后任何修改,都会直接写入主内存,所以不会出现线程的内存和主内存不一致的情况。
同样的,得到锁对象的时候,也是直接从主内存拿的。

synchronized缺点

1、效率低
锁不能人为释放,只能等执行完或者异常才能释放
Lock能解决这个问题(Lock可以设置超时时间,trylock方法)。
2、不灵活
相比读写锁,synchronized没分开读写,那读的时候也会加锁,是在没必要。

总结

单机服务,尽量少用synchronized
集群服务,禁止使用synchronized

虽然现在几乎不用synchronized了,但他的原理都是可以借鉴的,比如计数器+1的思路,解决可重入等等,其实包括现在的分布式锁,实现不一样,但说白了最终都是一样的,就是换个地方存计数器而已。redis分布式锁,相当于把计数器存在redis中,zookeeper分布式锁,相当于把计数器存在zookeeper中,数据库实现的,也是一样。

synchronized锁相关推荐

  1. 详解synchronized锁的各种用法及注意事项

    1 前言 本文主要通过简单的demo来阐述synchronized锁的各种用法以及使用synchronized锁的相关注意事项,记录下来同时也方便自己记忆. synchronized锁是jvm内置的锁 ...

  2. 多线程-synchronized锁

    package 多线程.synchronized锁; /*. * * * * */ public class Sale implements Runnable {private int m = 10; ...

  3. 【本人秃顶程序员】synchronized锁住的是代码还是对象

    ←←←←←←←←←←←← 快!点关注 不同的对象 public class Sync {public synchronized void test() {System.out.println(&quo ...

  4. 线程 synchronized锁机制

    脏读 一个常见的概念.在多线程中,难免会出现在多个线程中对同一个对象的实例变量进行并发访问的情况,如果不做正确的同步处理,那么产生的后果就是"脏读",也就是取到的数据其实是被更改过 ...

  5. synchronized锁的基本用法

    在多线程的情况下 需要是同一个对象锁 Synchronized(对象锁) { 需要保证线程安全的代码 } 1.修饰代码块,指定加锁对象,对给定对象加锁,进入同步代码快前要获得 给定对象 的锁. 2.修 ...

  6. Java线程同步:synchronized锁住的是代码还是对象

    在Java中,synchronized关键字是用来控制线程同步的,就是在多线程的环境下,控制synchronized代码段不被多个线程同时执行.synchronized既可以加在一段代码上,也可以加在 ...

  7. JUC多线程:synchronized锁机制原理 与 Lock锁机制

    前言: 线程安全是并发编程中的重要关注点,造成线程安全问题的主要原因有两点,一是存在共享数据(也称临界资源),二是存在多条线程共同操作共享数据.因此为了解决这个问题,我们可能需要这样一个方案,当存在多 ...

  8. 记一次synchronized锁字符串引发的坑兼再谈Java字符串

    问题描述 业务有一个需求,我把问题描述一下: 通过代理IP访问国外某网站N,每个IP对应一个固定的网站N的COOKIE,COOKIE有失效时间. 并发下,取IP是有一定策略的,取到IP之后拿IP对应的 ...

  9. 【Java多线程】实现Runnable接口方式 / 继承Thread类方式;使用synchronized锁实现线程安全;线程安全的懒汉式单例模式;死锁问题示例

    Thread 的生命周期 一.实现Runnable接口方式 1.在 run 方法中使用 synchronized 块 /*** 例子:创建三个窗口卖票,总票数为100张.使用实现Runnable接口的 ...

  10. Java多线程4:synchronized锁机制

    脏读 一个常见的概念.在多线程中,难免会出现在多个线程中对同一个对象的实例变量进行并发访问的情况,如果不做正确的同步处理,那么产生的后果就是"脏读",也就是取到的数据其实是被更改过 ...

最新文章

  1. SAP BW数据源增强管理
  2. 晚上八点半,一起来聊聊
  3. 获取aplicationContext对象,从而获取任何注入的对象
  4. Java Swing 如何关闭当前窗口?
  5. IntelliJ IDEA 文件夹重命名--解决重命名后js文件引用找不到路径报404错误
  6. php swoole能干,PHP swoole怎么用
  7. .gitignore文件不生效解决方法
  8. 3月22 坐标系转换,旋转矩阵,仿射变换,例子,相机与世界,欧拉角与轴角公式,一个坐标系下面的轨迹
  9. 王垠系列博文(题名外挂URL)
  10. 安装VC 6.0,出现 DOSX.EX must be in your AUTOEXEC.NT的信息
  11. 学习SpringBoot:知乎超赞回答:Java如何进阶?分享面经
  12. discuz mysql cpu 100_Discuz导致MYSQL CPU 占用 100%?
  13. 《计算机网络管理》_Chap2
  14. 番茄工作法总结-第七章:团队
  15. discuz 版块导航function_forumlist.php,Discuz! X2扩建左侧版块导航 社区层次一目了然...
  16. Java 反射?反射有什么缺点?你是怎么理解反射的(为什么框架需要反射)?
  17. apk包反编译,签名
  18. CKEditor的使用示例
  19. C语言连续自动自加怎么表示,为什么不建议在C语言中连续使用自增自减运算符...
  20. 在网页title加入icon图标

热门文章

  1. cdh中hdfs非ha环境迁移Namenode与secondaryNamenode,从uc机器到阿里;
  2. #35 string(缩点+动态规划)
  3. 如何在终端编译C++代码
  4. Ionic3 环境搭建以及基础配置实现(更新中)
  5. Jmeter生成html格式测试报告
  6. java.lang.UnsupportedClassVersionError: Bad version number in .class file异常
  7. 基于visual Studio2013解决面试题之0307最后谁剩下
  8. 日常小问题汇总(1)
  9. 数据结构——图的C语言实现
  10. Unity3D-声音系统